home *** CD-ROM | disk | FTP | other *** search
/ MacFormat España 22 / macformat_22.iso / Shareware / Programación / The Gray Council 1.1 / source / PowerPlant / GrayCouncilPP.cpp < prev    next >
Encoding:
Text File  |  1996-08-08  |  69.2 KB  |  2,887 lines  |  [TEXT/CWIE]

  1. //
  2. // GrayCouncilPP
  3. // Copyright ©1996 by Trygve Isaacson. All Rights Reserved.
  4. //
  5. // PowerPlant adapter classes for core Gray Council.
  6. //
  7. // Before using any of the GrayCouncil source code, read and
  8. // follow the licensing info in the accompanying documentation
  9. // or contact:
  10. //   <trygve@kagi.com>
  11. //   <http://www.kagi.com/authors/trygve/>
  12. //
  13. // GrayCouncil provides a set of standard C++ classes that implement
  14. // the standard Apple Grayscale Appearance. The core classes do not
  15. // require any other code such as a particular class framework.
  16. //
  17. // This file defines a set of helper classes that derive from standard
  18. // PowerPlant pane classes, and interface with the core Gray Council code.
  19. // There are also a couple of attachment subclasses for attaching to
  20. // other pane classes to get a white background and 3D frame.
  21. //
  22. // Normally, to use a GrayCouncil PowerPlant class, you can simply change the
  23. // class ID of the pane in your Constructor window resource to the
  24. // class ID of the appropriate Gray Council PowerPlant adapter class. For
  25. // example, to use the GC pushbutton, create a normal LButton pane,
  26. // and set its class ID to 'GCpb'. Voila. This also works for the LAttachment
  27. // subclasses defined here.
  28. //
  29. // A couple of the classes use the mUserCon field of the subview to specify
  30. // additional information such as icon IDs, string resource IDs, etc.
  31. //
  32. // If the mUserCon usage conflicts with what you are already doing with it,
  33. // you can use the "extended" pane subclasses (those whose class name ends
  34. // in "PPX" instead of "PP"). These classes read their additional info from
  35. // the pane resource stream instead of using mUserCon. In some cases they
  36. // let you specify additional options in the pane resource that you would
  37. // otherwise have to specify programmatically. The supplied resource file
  38. // named GCCustomPanes.rsrc contains the 'CPPb' custom pane definitions.
  39. // If you put this file in the Constructor app's folder, or keep it open
  40. // whenever your pane resource file is open, or paste the custom pane
  41. // types into your pane resource file, you can use the extended pane classes
  42. // in Constructor.
  43. //
  44. // Each class here that interfaces to a core AGAObject has a public
  45. // member variable called mAGAObject that points to the actual AGAObject
  46. // subclass object. Certain extended object settings (such as mixed-state
  47. // buttons, proportional and live scrolling, etc.) require you to call
  48. // the AGAObject to set it. The member variable is made public to keep
  49. // these MacApp classes as lightweight as possible; you make the call,
  50. // rather than using myriad new functions of the PowerPlant AGA subclasses.
  51. //
  52. // Classes defined below:
  53. //    AGAWindowPP -- LWindow subclass that draws a modeless window gray
  54. //        background.
  55. //    AGADialogBoxPP -- LDialogBox subclass that draws a modal window gray
  56. //        background and replaces the PowerPlant default button outline by
  57. //        altering the style of the default button AGAPushButton object.
  58. //    AGAPushButtonPP -- LStdButton subclass for AGAPushButton.
  59. //    AGACheckBoxPP -- LStdCheckBox subclass for AGACheckBox.
  60. //    AGARadioButtonPP -- LStdRadioButton subclass for AGARadioButton.
  61. //    AGAIconPushButtonPP -- AGAPushButtonPP (LStdButton) subclass for
  62. //        AGAIconPushButton.
  63. //    AGAIconPushButtonPPX -- AGAIconPushButtonPP (LStdButton) subclass for
  64. //        AGAIconPushButton, that uses extended CPPb data for the icon ID.
  65. //    AGAIconCheckBoxPP -- AGACheckBoxPP (LStdCheckBox) subclass for
  66. //        AGAIconCheckBox.
  67. //    AGAIconCheckBoxPPX -- AGAIconCheckBoxPP (LStdCheckBox) subclass for
  68. //        AGAIconCheckBox, that uses extended CPPb data for the icon IDs.
  69. //    AGAIconRadioButtonPP -- AGARadioButtonPP (LStdRadioButton) subclass
  70. //        for AGAIconRadioButton.
  71. //    AGAIconRadioButtonPPX -- AGAIconRadioButtonPP (LStdRadioButton) subclass
  72. //        for AGAIconRadioButton, that uses extended CPPb data for the icon IDs.
  73. //    AGAIconRadioButtonMA -- AGARadioButtonMA (LStdRadioButton) subclass for
  74. //        AGAIconRadioButton.
  75. //    AGAGroupBoxPP -- LGroupBox subclass for AGAGroupBox, with primary group
  76. //        box appearance.
  77. //    AGAGroupBoxPPX -- AGAGroupBoxPP (LGroupBox) subclass for AGAGroupBox,
  78. //        that uses extended CPPb data for the box type and gap pane ID.
  79. //    AGASecondaryGroupBoxPP -- AGAGroupBoxPP (LGroupBox) subclass for
  80. //        AGAGroupBox, with secondary group box appearance.
  81. //    AGAScrollBarPP -- LStdControl subclass for AGAScrollBar.
  82. //    AGAScrollerPP -- LScroller subclass that replaces the normal LStdControl
  83. //        scroll bars with ones of class AGAScrollBarPP, and correctly
  84. //        maintain them during scrolling.
  85. //    AGASliderPP -- LControl subclass for AGASlider.
  86. //    AGASliderPPX -- AGASliderPP (LControl) subclass for AGASlider, that
  87. //        uses extended CPPb data for the label strings ID, style, and
  88. //        slider justification.
  89. //    AGALittleArrowsPP -- LControl subclass for AGALittleArrows.
  90. //    AGALittleArrowsPPX -- AGALittleArrowsPP (LControl) subclass for
  91. //        AGALittleArrows, that uses extended CPPb data for the linked
  92. //        numeric LEditField pane ID.
  93. //    AGAPopupMenuPP -- LStdPopupMenu subclass for AGAPopupMenu.
  94. //    AGADisclosureTrianglePP -- LControl subclass for AGADisclosureTriangle.
  95. //    AGAProgressIndicatorPP -- LControl subclass for AGAProgressIndicator.
  96. //    AGAWhiteBackgroundAttachmentPP -- LAttachment subclass that draws a
  97. //        white background for the pane to which it is attached.
  98. //    AGABorderFrameAttachmentPP -- LAttachment subclass that draws a
  99. //        "3D" sunken frame around the pane to which it is attached.
  100. //    AGAEditFieldPP -- LEditField subclass that automatically attaches an
  101. //        AGAWhiteBackgroundAttachmentPP and an AGABorderFrameAttachmentPP,
  102. //        and also knows how to draw the frame in disabled gray when disabled.
  103. //    AGATextEditPP -- LTextEdit subclass that automatically attaches an
  104. //        AGAWhiteBackgroundAttachmentPP and an AGABorderFrameAttachmentPP.
  105. //    AGASeparatorPP -- LPane subclass for AGASeparator.
  106. //    AGACaptionPP -- LCaption subclass for AGAStaticText.
  107. //    AGAFocusBoxPP -- LFocusBox subclass used by AGAListBox to draw the
  108. //        list box focus frame.
  109. //    AGAListBoxPP -- LListBox subclass that automatically attaches an
  110. //        AGAWhiteBackgroundAttachmentPP and an AGABorderFrameAttachmentPP,
  111. //        and also replaces the normal LFocusBox with an AGAFocusBoxPP so
  112. //        that the focus frame appears correct.
  113. //
  114.  
  115. #include "GrayCouncilPP.h"
  116.  
  117. // There are 3 places in this file that use run-time type
  118. // information (RTTI). This requires turning on the RTTI switch
  119. // in the CodeWarrior C/C++ Language preferences panel. If for
  120. // some reason you can't do this, simply #define NO_RTTI here
  121. // and the RTTI-dependent code will be skipped. But if you do
  122. // this, check the comments below where the RTTI usage is so
  123. // that you don't violate the constraints that the RTTI usage
  124. // was checking for.
  125.  
  126. #ifndef NO_RTTI
  127. #include <typeinfo.h>
  128. #endif // NO_RTTI
  129.  
  130. // The URegistrar::RegisterClass calls are making my eyes hurt.
  131. // Define a macro to do it instead. We take advantage of the fact that
  132. // we use the names class_ID and CreateStream in all of our classes.
  133. #define GCPP_REGISTER_CLASS(classname) URegistrar::RegisterClass(classname::class_ID, (ClassCreatorFunc) classname::CreateStream)
  134.  
  135. OSErr InitGrayCouncilPP()
  136.     {
  137.     //
  138.     // Register our dynamically instantiated pane & attachment subclasses.
  139.     //
  140.  
  141.     GCPP_REGISTER_CLASS(AGAWhiteBackgroundAttachmentPP);
  142.     GCPP_REGISTER_CLASS(AGABorderFrameAttachmentPP);
  143.     GCPP_REGISTER_CLASS(AGAWindowPP);
  144.     GCPP_REGISTER_CLASS(AGADialogBoxPP);
  145.     GCPP_REGISTER_CLASS(AGAPushButtonPP);
  146.     GCPP_REGISTER_CLASS(AGACheckBoxPP);
  147.     GCPP_REGISTER_CLASS(AGARadioButtonPP);
  148.     GCPP_REGISTER_CLASS(AGAIconPushButtonPP);
  149.     GCPP_REGISTER_CLASS(AGAIconPushButtonPPX);
  150.     GCPP_REGISTER_CLASS(AGAIconCheckBoxPP);
  151.     GCPP_REGISTER_CLASS(AGAIconCheckBoxPPX);
  152.     GCPP_REGISTER_CLASS(AGAIconRadioButtonPP);
  153.     GCPP_REGISTER_CLASS(AGAIconRadioButtonPPX);
  154.     GCPP_REGISTER_CLASS(AGAScrollBarPP);
  155.     GCPP_REGISTER_CLASS(AGAScrollerPP);
  156.     GCPP_REGISTER_CLASS(AGAGroupBoxPP);
  157.     GCPP_REGISTER_CLASS(AGAGroupBoxPPX);
  158.     GCPP_REGISTER_CLASS(AGASecondaryGroupBoxPP);
  159.     GCPP_REGISTER_CLASS(AGASliderPP);
  160.     GCPP_REGISTER_CLASS(AGASliderPPX);
  161.     GCPP_REGISTER_CLASS(AGALittleArrowsPP);
  162.     GCPP_REGISTER_CLASS(AGALittleArrowsPPX);
  163.     GCPP_REGISTER_CLASS(AGAPopupMenuPP);
  164.     GCPP_REGISTER_CLASS(AGADisclosureTrianglePP);
  165.     GCPP_REGISTER_CLASS(AGAProgressIndicatorPP);
  166.     GCPP_REGISTER_CLASS(AGAEditFieldPP);
  167.     GCPP_REGISTER_CLASS(AGATextEditPP);
  168.     GCPP_REGISTER_CLASS(AGASeparatorPP);
  169.     GCPP_REGISTER_CLASS(AGAListBoxPP);
  170.     GCPP_REGISTER_CLASS(AGAFocusBoxPP);
  171.     GCPP_REGISTER_CLASS(AGACaptionPP);
  172.  
  173.     // Do Core Gray Council initialization.
  174.     return InitGrayCouncil();
  175.     }
  176.  
  177. static SInt32 MinSInt32(SInt32 a, SInt32 b) { return (a < b) ? a : b; }
  178. static SInt32 MaxSInt32(SInt32 a, SInt32 b) { return (a > b) ? a : b; }
  179.  
  180. static SInt32 GetTextTraitsJustification(ResIDT inTextTraitsID)
  181.     {
  182.     TextTraitsH    aTTHandle = UTextTraits::LoadTextTraits(inTextTraitsID);
  183.     
  184.     if (aTTHandle == NULL)
  185.         return teFlushDefault;
  186.     else
  187.         return (**aTTHandle).justification;
  188.     }
  189.  
  190. //
  191. // AGAWindowPP ----------------------------------------------------
  192. //
  193.  
  194. #undef Inherited
  195. #define Inherited LWindow
  196.  
  197. AGAWindowPP* AGAWindowPP::CreateStream(LStream* inStream)
  198.     {
  199.     return new AGAWindowPP(inStream);
  200.     }
  201.  
  202. AGAWindowPP::AGAWindowPP(LStream* inStream)
  203. : Inherited(inStream)
  204.     {
  205.     }
  206.  
  207. AGAWindowPP::~AGAWindowPP()
  208.     {
  209.     }
  210.  
  211. void AGAWindowPP::FinishCreate()
  212.     {
  213.     // Make sure that the gray background color is installed
  214.     // prior to subpanes having their FinishCreateSelf method
  215.     // called.
  216.  
  217.     this->SetForeAndBackColors(NULL, &gAGARamp[r2]);
  218.     
  219.     Inherited::FinishCreate();
  220.     }
  221.  
  222. void AGAWindowPP::FinishCreateSelf()
  223.     {
  224.     // Let LWindow do its normal stuff first.
  225.     
  226.     Inherited::FinishCreateSelf();
  227.     
  228.     // Install gray background color.
  229.     this->SetForeAndBackColors(NULL, &gAGARamp[r2]);
  230.     }
  231.  
  232. void AGAWindowPP::DrawSelf()
  233.     {
  234.     // Change normal DrawSelf by drawing our background.
  235.  
  236.     if (HasAttribute(windAttr_EraseOnUpdate))
  237.         this->DrawBackground(&mMacWindowP->portRect, TRUE, mActive == triState_On);
  238.     
  239.     this->DrawSizeBox();
  240.     }
  241.  
  242. void AGAWindowPP::ResizeFrameBy(Int16 inWidthDelta, Int16 inHeightDelta, Boolean inRefresh)
  243.     {
  244.     // If the window size is changing in either direction, we need
  245.     // to invalidate the right/bottom edge pixels that will
  246.     // need to turn gray when the window is expanded, either before
  247.     // or after the resize.
  248.     
  249.     this->InvalidateEdges(TRUE, inWidthDelta, inHeightDelta);
  250.  
  251.     Inherited::ResizeFrameBy(inWidthDelta, inHeightDelta, inRefresh);
  252.     
  253.     this->InvalidateEdges(FALSE, inWidthDelta, inHeightDelta);
  254.     }
  255.  
  256. void AGAWindowPP::ActivateSelf()
  257.     {
  258.     // Redraw just the edge pixels that change based on active state.
  259.  
  260.     this->FocusDraw();
  261.     this->DrawBackground(&mMacWindowP->portRect, FALSE, TRUE);
  262.     
  263.     Inherited::ActivateSelf();
  264.     }
  265.  
  266. void AGAWindowPP::DeactivateSelf()
  267.     {
  268.     // Redraw just the edge pixels that change based on active state.
  269.  
  270.     this->FocusDraw();
  271.     this->DrawBackground(&mMacWindowP->portRect, FALSE, FALSE);
  272.     
  273.     Inherited::DeactivateSelf();
  274.     }
  275.  
  276. void AGAWindowPP::DrawBackground(const Rect* area, Boolean fill, Boolean active)
  277.     {
  278.     AGABackgroundPaint(area, fill, kIsNotModal, active, (mAttributes & windAttr_SizeBox) != 0);
  279.     }
  280.  
  281. void AGAWindowPP::InvalidateEdges(Boolean before, Int16 inWidthDelta, Int16 inHeightDelta)
  282.     {
  283.     // Invalidate the extra "edge" pixels that need to be redrawn
  284.     // when the window is resized.
  285.  
  286.     Rect    bounds;
  287.     Rect    rectToInvalidate;
  288.     
  289.     this->CalcPortFrameRect(bounds);
  290.  
  291.     if (((inWidthDelta > 0) && before) ||
  292.         ((inWidthDelta < 0) && ! before))
  293.         {
  294.         rectToInvalidate = bounds;
  295.         rectToInvalidate.left = rectToInvalidate.right - 1;
  296.         this->InvalPortRect(&rectToInvalidate);
  297.         }
  298.     
  299.     if (((inHeightDelta > 0) && before) ||
  300.         ((inHeightDelta < 0) && ! before))
  301.         {
  302.         rectToInvalidate = bounds;
  303.         rectToInvalidate.top = rectToInvalidate.bottom - 1;
  304.         this->InvalPortRect(&rectToInvalidate);
  305.         }
  306.     
  307.     if ((mAttributes & windAttr_SizeBox) != 0)
  308.         {
  309.         rectToInvalidate = bounds;
  310.         rectToInvalidate.left = rectToInvalidate.right - 16;
  311.         rectToInvalidate.top = rectToInvalidate.bottom - 16;
  312.         this->InvalPortRect(&rectToInvalidate);
  313.         }
  314.     }
  315.  
  316. //
  317. // AGADialogBoxPP ----------------------------------------------------
  318. //
  319.  
  320. #undef Inherited
  321. #define Inherited LDialogBox
  322.  
  323. AGADialogBoxPP* AGADialogBoxPP::CreateStream(LStream* inStream)
  324.     {
  325.     return new AGADialogBoxPP(inStream);
  326.     }
  327.  
  328. AGADialogBoxPP::AGADialogBoxPP(LStream* inStream)
  329. : Inherited(inStream)
  330.     {
  331.     mDeleteDefaultOutline = FALSE;
  332.     }
  333.  
  334. AGADialogBoxPP::~AGADialogBoxPP()
  335.     {
  336.     }
  337.  
  338. void AGADialogBoxPP::FinishCreate()
  339.     {
  340.     // Make sure that the gray background color is installed
  341.     // prior to subpanes having their FinishCreateSelf method
  342.     // called.
  343.  
  344.     this->SetForeAndBackColors(NULL, &gAGARamp[r2]);
  345.     
  346.     Inherited::FinishCreate();
  347.     }
  348.  
  349. void AGADialogBoxPP::FinishCreateSelf()
  350.     {
  351.     // Let LDialogBox do its normal stuff first.
  352.     
  353.     Inherited::FinishCreateSelf();
  354.     
  355.     // Install gray background color.
  356.     this->SetForeAndBackColors(NULL, &gAGARamp[r2]);
  357.     
  358.     //
  359.     // Now we remove its LDefaultOutline and set the
  360.     // default our way.
  361.     //
  362.     
  363.     if (mDefaultOutline != NULL)
  364.         {
  365.         delete mDefaultOutline;
  366.         mDefaultOutline = NULL;
  367.         }
  368.  
  369.     this->SetDefaultButton(mDefaultButtonID);
  370.     }
  371.  
  372. void AGADialogBoxPP::SetDefaultButton(PaneIDT inButtonID)
  373.     {
  374.     // If you bypass the RTTI here, you must ensure that the
  375.     // panes represented by the mDefaultButtonID and the
  376.     // inButtonID are subclass of AGAPushButtonPP.
  377.  
  378.     AGAPushButtonPP*    oldDefaultButton = NULL;
  379.     AGAPushButtonPP*    newDefaultButton = NULL;
  380.     LPane*                oldDefaultPane = this->FindPaneByID(mDefaultButtonID);
  381.     LPane*                newDefaultPane = this->FindPaneByID(inButtonID);
  382.  
  383. #ifndef NO_RTTI
  384.  
  385.     if (oldDefaultPane != NULL)
  386.         oldDefaultButton = dynamic_cast<AGAPushButtonPP*>(oldDefaultPane);
  387.  
  388.     if (newDefaultPane != NULL)
  389.         newDefaultButton = dynamic_cast<AGAPushButtonPP*>(newDefaultPane);
  390.  
  391. #else // NO_RTTI
  392.  
  393.     oldDefaultButton = (AGAPushButtonPP*) oldDefaultPane;
  394.     newDefaultButton = (AGAPushButtonPP*) newDefaultPane;
  395.  
  396. #endif // NO_RTTI
  397.  
  398.     mDefaultButtonID = inButtonID;
  399.     
  400.     if (oldDefaultButton != NULL)
  401.         {
  402.         // Tell the old default button that it is no longer
  403.         // the default.
  404.  
  405.         oldDefaultButton->mAGAObject->SetDefault(AGAObject::kIsNotDefault, AGAObject::kFrameOutside);
  406.         oldDefaultButton->Refresh();
  407.         }
  408.     else if (mDefaultOutline != nil)
  409.         {
  410.         // Not an AGA object. Do it the LDialogBox way...
  411.  
  412.         mDefaultOutline->Refresh();
  413.         delete mDefaultOutline;
  414.         mDefaultOutline = NULL;
  415.         }
  416.     
  417.     if (newDefaultButton != NULL)
  418.         {
  419.         // Tell the new default button that it has become
  420.         // the default.
  421.  
  422.         newDefaultButton->mAGAObject->SetDefault(AGAObject::kIsDefault, AGAObject::kFrameOutside);
  423.         newDefaultButton->Refresh();
  424.         }
  425.     else if (newDefaultPane != NULL)
  426.         {
  427.         // Not an AGA object. Do it the LDialogBox way...
  428.  
  429.         ((LControl*) newDefaultPane)->AddListener(this);
  430.         mDefaultOutline = new LDefaultOutline(newDefaultPane);
  431.         mDefaultOutline->Refresh();
  432.         }
  433.     }
  434.  
  435. void AGADialogBoxPP::DrawSelf()
  436.     {
  437.     // Change normal DrawSelf by drawing our background.
  438.  
  439.     if (HasAttribute(windAttr_EraseOnUpdate))
  440.         this->DrawBackground(&mMacWindowP->portRect, TRUE, mActive == triState_On);
  441.     
  442.     this->DrawSizeBox();
  443.     }
  444.  
  445. void AGADialogBoxPP::ResizeFrameBy(Int16 inWidthDelta, Int16 inHeightDelta, Boolean inRefresh)
  446.     {
  447.     // If the window size is changing in either direction, we need
  448.     // to invalidate the right/bottom edge pixels that will
  449.     // need to turn gray when the window is expanded, either before
  450.     // or after the resize.
  451.     
  452.     this->InvalidateEdges(TRUE, inWidthDelta, inHeightDelta);
  453.  
  454.     Inherited::ResizeFrameBy(inWidthDelta, inHeightDelta, inRefresh);
  455.     
  456.     this->InvalidateEdges(FALSE, inWidthDelta, inHeightDelta);
  457.     }
  458.  
  459. void AGADialogBoxPP::ActivateSelf()
  460.     {
  461.     // Redraw just the edge pixels that change based on active state.
  462.  
  463.     this->FocusDraw();
  464.     this->DrawBackground(&mMacWindowP->portRect, FALSE, TRUE);
  465.     
  466.     Inherited::ActivateSelf();
  467.     }
  468.  
  469. void AGADialogBoxPP::DeactivateSelf()
  470.     {
  471.     // Redraw just the edge pixels that change based on active state.
  472.  
  473.     this->FocusDraw();
  474.     this->DrawBackground(&mMacWindowP->portRect, FALSE, FALSE);
  475.     
  476.     Inherited::DeactivateSelf();
  477.     }
  478.  
  479. void AGADialogBoxPP::DrawBackground(const Rect* area, Boolean fill, Boolean active)
  480.     {
  481.     AGABackgroundPaint(area, fill, kIsModal, active, (mAttributes & windAttr_SizeBox) != 0);
  482.     }
  483.  
  484. void AGADialogBoxPP::InvalidateEdges(Boolean before, Int16 inWidthDelta, Int16 inHeightDelta)
  485.     {
  486.     // Invalidate the extra "edge" pixels that need to be redrawn
  487.     // when the window is resized.
  488.  
  489.     Rect    bounds;
  490.     Rect    rectToInvalidate;
  491.     
  492.     this->CalcPortFrameRect(bounds);
  493.  
  494.     if (((inWidthDelta > 0) && before) ||
  495.         ((inWidthDelta < 0) && ! before))
  496.         {
  497.         rectToInvalidate = bounds;
  498.         rectToInvalidate.left = rectToInvalidate.right - 1;
  499.         this->InvalPortRect(&rectToInvalidate);
  500.         }
  501.     
  502.     if (((inHeightDelta > 0) && before) ||
  503.         ((inHeightDelta < 0) && ! before))
  504.         {
  505.         rectToInvalidate = bounds;
  506.         rectToInvalidate.top = rectToInvalidate.bottom - 1;
  507.         this->InvalPortRect(&rectToInvalidate);
  508.         }
  509.     
  510.     if ((mAttributes & windAttr_SizeBox) != 0)
  511.         {
  512.         rectToInvalidate = bounds;
  513.         rectToInvalidate.left = rectToInvalidate.right - 16;
  514.         rectToInvalidate.top = rectToInvalidate.bottom - 16;
  515.         this->InvalPortRect(&rectToInvalidate);
  516.         }
  517.     }
  518.  
  519. //
  520. // AGAPushButtonPP ----------------------------------------------------
  521. //
  522.  
  523. #undef Inherited
  524. #define Inherited LStdButton
  525.  
  526. AGAPushButtonPP* AGAPushButtonPP::CreateStream(LStream* inStream)
  527.     {
  528.     return new AGAPushButtonPP(inStream);
  529.     }
  530.  
  531. AGAPushButtonPP::AGAPushButtonPP(LStream* inStream)
  532. : Inherited(inStream)
  533.     {
  534.     mAGAObject = NULL;
  535.     }
  536.  
  537. AGAPushButtonPP::~AGAPushButtonPP()
  538.     {
  539.     // Delete AGA object if we successfully allocated it.
  540.  
  541.     if (mAGAObject != NULL)
  542.         delete mAGAObject;
  543.     }
  544.  
  545. void AGAPushButtonPP::FinishCreateSelf()
  546.     {
  547.     // Create and set up the AGAObject.
  548.  
  549.     this->HideSelf();    // make sure the Control Manager object is not drawn
  550.     
  551.     this->CreateAGAObject();
  552.     }
  553.  
  554. void AGAPushButtonPP::DrawSelf()
  555.     {
  556.     // Let the AGAObject draw itself.
  557.  
  558.     if (mAGAObject != NULL)
  559.         mAGAObject->DrawObject();
  560.     }
  561.  
  562. void AGAPushButtonPP::ClickSelf(const SMouseDownEvent &inMouseDown)
  563.     {
  564.     // Let the AGAObject track the mouse.
  565.  
  566.     if (mAGAObject != NULL)
  567.         {
  568.         this->FocusDraw();
  569.         
  570.         if (mAGAObject->TrackMouse(inMouseDown.whereLocal))
  571.             this->HotSpotResult(this->FindHotSpot(inMouseDown.whereLocal));
  572.         }
  573.     }
  574.  
  575. void AGAPushButtonPP::HotSpotAction(SInt16 inHotSpot, Boolean inCurrInside, Boolean inPrevInside)
  576.     {
  577.     // Draw the button based on the new press state.
  578.  
  579.     if (mAGAObject != NULL)
  580.         {
  581.         this->FocusDraw();
  582.         mAGAObject->DrawButton(inCurrInside);
  583.         }
  584.     }
  585.  
  586. void AGAPushButtonPP::EnableSelf()
  587.     {
  588.     // Let the AGAObject enable itself.
  589.  
  590.     if (mAGAObject != NULL)
  591.         {
  592.         this->FocusDraw();
  593.         mAGAObject->SetEnable(AGAObject::kEnabled, AGAObject::kRedraw);
  594.         }
  595.     }
  596.  
  597. void AGAPushButtonPP::DisableSelf()
  598.     {
  599.     // Let the AGAObject disable itself.
  600.  
  601.     if (mAGAObject != NULL)
  602.         {
  603.         this->FocusDraw();
  604.         mAGAObject->SetEnable(AGAObject::kDisabled, AGAObject::kRedraw);
  605.         }
  606.     }
  607.  
  608. void AGAPushButtonPP::ShowSelf()
  609.     {
  610.     // Suppress showing the Control Manager control.
  611.     }
  612.  
  613. void AGAPushButtonPP::CreateAGAObject()
  614.     {
  615.     // Instantiate the particular AGAObject subclass.
  616.  
  617.     Rect    bounds;
  618.     Str255    title;
  619.     
  620.     (void) this->CalcLocalFrameRect(bounds);
  621.     ::GetControlTitle(mMacControlH, title);
  622.  
  623.     ThrowIfNil_(mAGAObject = new AGAPushButton(&bounds, AGATextStyle(mTextTraitsID), title));
  624.  
  625.     if (mEnabled == triState_Off)
  626.         mAGAObject->SetEnable(AGAObject::kDisabled, AGAObject::kDontRedraw);
  627.     }
  628.  
  629. //
  630. // AGACheckBoxPP ----------------------------------------------------
  631. //
  632.  
  633. #undef Inherited
  634. #define Inherited LStdCheckBox
  635.  
  636. AGACheckBoxPP* AGACheckBoxPP::CreateStream(LStream* inStream)
  637.     {
  638.     return new AGACheckBoxPP(inStream);
  639.     }
  640.  
  641. AGACheckBoxPP::AGACheckBoxPP(LStream* inStream)
  642. : Inherited(inStream)
  643.     {
  644.     mAGAObject = NULL;
  645.     }
  646.  
  647. AGACheckBoxPP::~AGACheckBoxPP()
  648.     {
  649.     // Delete AGA object if we successfully allocated it.
  650.  
  651.     if (mAGAObject != NULL)
  652.         delete mAGAObject;
  653.     }
  654.  
  655. void AGACheckBoxPP::FinishCreateSelf()
  656.     {
  657.     // Create and set up the AGAObject.
  658.  
  659.     this->HideSelf();    // make sure the Control Manager object is not drawn
  660.     
  661.     this->CreateAGAObject();
  662.     }
  663.  
  664. void AGACheckBoxPP::DrawSelf()
  665.     {
  666.     // Let the AGAObject draw itself.
  667.  
  668.     if (mAGAObject != NULL)
  669.         mAGAObject->DrawObject();
  670.     }
  671.  
  672. void AGACheckBoxPP::ClickSelf(const SMouseDownEvent &inMouseDown)
  673.     {
  674.     // Let the AGAObject track the mouse.
  675.  
  676.     if (mAGAObject != NULL)
  677.         {
  678.         this->FocusDraw();
  679.         
  680.         if (mAGAObject->TrackMouse(inMouseDown.whereLocal))
  681.             this->HotSpotResult(this->FindHotSpot(inMouseDown.whereLocal));
  682.         }
  683.     }
  684.  
  685. void AGACheckBoxPP::HotSpotAction(SInt16 inHotSpot, Boolean inCurrInside, Boolean inPrevInside)
  686.     {
  687.     // Draw the button based on the new press state.
  688.  
  689.     if (mAGAObject != NULL)
  690.         {
  691.         this->FocusDraw();
  692.         mAGAObject->DrawButton(inCurrInside);
  693.         }
  694.     }
  695.  
  696. void AGACheckBoxPP::EnableSelf()
  697.     {
  698.     // Let the AGAObject enable itself.
  699.  
  700.     if (mAGAObject != NULL)
  701.         {
  702.         this->FocusDraw();
  703.         mAGAObject->SetEnable(AGAObject::kEnabled, AGAObject::kRedraw);
  704.         }
  705.     }
  706.  
  707. void AGACheckBoxPP::DisableSelf()
  708.     {
  709.     // Let the AGAObject disable itself.
  710.  
  711.     if (mAGAObject != NULL)
  712.         {
  713.         this->FocusDraw();
  714.         mAGAObject->SetEnable(AGAObject::kDisabled, AGAObject::kRedraw);
  715.         }
  716.     }
  717.  
  718. void AGACheckBoxPP::ShowSelf()
  719.     {
  720.     // Suppress showing the Control Manager control.
  721.     }
  722.  
  723. void AGACheckBoxPP::SetValue(SInt32 inValue)
  724.     {
  725.     // Set the actual LControl value and the AGA object value.
  726.  
  727.     Inherited::SetValue(inValue);
  728.  
  729.     if (mAGAObject != NULL)
  730.         {
  731.         this->FocusDraw();
  732.         mAGAObject->SetValue(inValue, AGAObject::kRedraw);
  733.         }
  734.     }
  735.  
  736. void AGACheckBoxPP::CreateAGAObject()
  737.     {
  738.     // Instantiate the particular AGAObject subclass.
  739.  
  740.     Rect    bounds;
  741.     Str255    title;
  742.     
  743.     (void) this->CalcLocalFrameRect(bounds);
  744.     ::GetControlTitle(mMacControlH, title);
  745.  
  746.     ThrowIfNil_(mAGAObject = new AGACheckBox(&bounds, AGATextStyle(mTextTraitsID), title, AGAObject::kNoAutomaticState));
  747.  
  748.     if (mEnabled == triState_Off)
  749.         mAGAObject->SetEnable(AGAObject::kDisabled, AGAObject::kDontRedraw);
  750.  
  751.     mAGAObject->SetValue(this->GetValue(), AGAObject::kDontRedraw);
  752.     }
  753.  
  754. //
  755. // AGARadioButtonPP ----------------------------------------------------
  756. //
  757.  
  758. #undef Inherited
  759. #define Inherited LStdRadioButton
  760.  
  761. AGARadioButtonPP* AGARadioButtonPP::CreateStream(LStream* inStream)
  762.     {
  763.     return new AGARadioButtonPP(inStream);
  764.     }
  765.  
  766. AGARadioButtonPP::AGARadioButtonPP(LStream* inStream)
  767. : Inherited(inStream)
  768.     {
  769.     mAGAObject = NULL;
  770.     }
  771.  
  772. AGARadioButtonPP::~AGARadioButtonPP()
  773.     {
  774.     // Delete AGA object if we successfully allocated it.
  775.  
  776.     if (mAGAObject != NULL)
  777.         delete mAGAObject;
  778.     }
  779.  
  780. void AGARadioButtonPP::FinishCreateSelf()
  781.     {
  782.     // Create and set up the AGAObject.
  783.  
  784.     this->HideSelf();    // make sure the Control Manager object is not drawn
  785.     
  786.     this->CreateAGAObject();
  787.     }
  788.  
  789. void AGARadioButtonPP::DrawSelf()
  790.     {
  791.     // Let the AGAObject draw itself.
  792.  
  793.     if (mAGAObject != NULL)
  794.         mAGAObject->DrawObject();
  795.     }
  796.  
  797. void AGARadioButtonPP::ClickSelf(const SMouseDownEvent &inMouseDown)
  798.     {
  799.     // Let the AGAObject track the mouse.
  800.  
  801.     if (mAGAObject != NULL)
  802.         {
  803.         this->FocusDraw();
  804.         
  805.         if (mAGAObject->TrackMouse(inMouseDown.whereLocal))
  806.             this->HotSpotResult(this->FindHotSpot(inMouseDown.whereLocal));
  807.         }
  808.     }
  809.  
  810. void AGARadioButtonPP::HotSpotAction(SInt16 inHotSpot, Boolean inCurrInside, Boolean inPrevInside)
  811.     {
  812.     // Draw the button based on the new press state.
  813.  
  814.     if (mAGAObject != NULL)
  815.         {
  816.         this->FocusDraw();
  817.         mAGAObject->DrawButton(inCurrInside);
  818.         }
  819.     }
  820.  
  821. void AGARadioButtonPP::EnableSelf()
  822.     {
  823.     // Let the AGAObject enable itself.
  824.  
  825.     if (mAGAObject != NULL)
  826.         {
  827.         this->FocusDraw();
  828.         mAGAObject->SetEnable(AGAObject::kEnabled, AGAObject::kRedraw);
  829.         }
  830.     }
  831.  
  832. void AGARadioButtonPP::DisableSelf()
  833.     {
  834.     // Let the AGAObject disable itself.
  835.  
  836.     if (mAGAObject != NULL)
  837.         {
  838.         this->FocusDraw();
  839.         mAGAObject->SetEnable(AGAObject::kDisabled, AGAObject::kRedraw);
  840.         }
  841.     }
  842.  
  843. void AGARadioButtonPP::ShowSelf()
  844.     {
  845.     // Suppress showing the Control Manager control.
  846.     }
  847.  
  848. void AGARadioButtonPP::SetValue(SInt32 inValue)
  849.     {
  850.     // Set the actual LControl value and the AGA object value.
  851.  
  852.     Inherited::SetValue(inValue);
  853.  
  854.     if (mAGAObject != NULL)
  855.         {
  856.         this->FocusDraw();
  857.         mAGAObject->SetValue(inValue, AGAObject::kRedraw);
  858.         }
  859.     }
  860.  
  861. void AGARadioButtonPP::CreateAGAObject()
  862.     {
  863.     // Instantiate the particular AGAObject subclass.
  864.  
  865.     Rect    bounds;
  866.     Str255    title;
  867.     
  868.     (void) this->CalcLocalFrameRect(bounds);
  869.     ::GetControlTitle(mMacControlH, title);
  870.  
  871.     ThrowIfNil_(mAGAObject = new AGARadioButton(&bounds, AGATextStyle(mTextTraitsID), title, kNoGroupID, kNoGroupID, AGAObject::kNoAutomaticState));
  872.  
  873.     if (mEnabled == triState_Off)
  874.         mAGAObject->SetEnable(AGAObject::kDisabled, AGAObject::kDontRedraw);
  875.  
  876.     mAGAObject->SetValue(this->GetValue(), AGAObject::kDontRedraw);
  877.     }
  878.  
  879. //
  880. // AGAIconPushButtonPP ----------------------------------------------------
  881. //
  882.  
  883. #undef Inherited
  884. #define Inherited AGAPushButtonPP
  885.  
  886. AGAIconPushButtonPP* AGAIconPushButtonPP::CreateStream(LStream* inStream)
  887.     {
  888.     return new AGAIconPushButtonPP(inStream);
  889.     }
  890.  
  891. AGAIconPushButtonPP::AGAIconPushButtonPP(LStream* inStream)
  892. : Inherited(inStream)
  893.     {
  894.     // Use the mUserCon for the icon ID.
  895.  
  896.     mIconID = mUserCon;
  897.     }
  898.  
  899. AGAIconPushButtonPP::~AGAIconPushButtonPP()
  900.     {
  901.     }
  902.  
  903. void AGAIconPushButtonPP::CreateAGAObject()
  904.     {
  905.     // Instantiate the particular AGAObject subclass.
  906.  
  907.     Rect    bounds;
  908.     
  909.     (void) this->CalcLocalFrameRect(bounds);
  910.  
  911.     ThrowIfNil_(mAGAObject = new AGAIconPushButton(&bounds, mIconID, MIconButtonObject::GetDefaultIconType(bounds.right - bounds.left)));
  912.     }
  913.  
  914. //
  915. // AGAIconPushButtonPPX ----------------------------------------------------
  916. //
  917.  
  918. #undef Inherited
  919. #define Inherited AGAIconPushButtonPP
  920.  
  921. AGAIconPushButtonPPX* AGAIconPushButtonPPX::CreateStream(LStream* inStream)
  922.     {
  923.     return new AGAIconPushButtonPPX(inStream);
  924.     }
  925.  
  926. AGAIconPushButtonPPX::AGAIconPushButtonPPX(LStream* inStream)
  927. : Inherited(inStream)
  928.     {
  929.     // Read the icon ID from the stream.
  930.  
  931.     inStream->ReadData(&mIconID, sizeof(mIconID));
  932.     }
  933.  
  934. AGAIconPushButtonPPX::~AGAIconPushButtonPPX()
  935.     {
  936.     }
  937.  
  938. //
  939. // AGAIconCheckBoxPP ----------------------------------------------------
  940. //
  941.  
  942. #undef Inherited
  943. #define Inherited AGACheckBoxPP
  944.  
  945. AGAIconCheckBoxPP* AGAIconCheckBoxPP::CreateStream(LStream* inStream)
  946.     {
  947.     return new AGAIconCheckBoxPP(inStream);
  948.     }
  949.  
  950. AGAIconCheckBoxPP::AGAIconCheckBoxPP(LStream* inStream)
  951. : Inherited(inStream)
  952.     {
  953.     // Use the mUserCon for both icon IDs.
  954.  
  955.     mOffIconID = mUserCon;
  956.     mOnIconID = mUserCon;
  957.     }
  958.  
  959. AGAIconCheckBoxPP::~AGAIconCheckBoxPP()
  960.     {
  961.     }
  962.  
  963. void AGAIconCheckBoxPP::CreateAGAObject()
  964.     {
  965.     // Instantiate the particular AGAObject subclass.
  966.     Rect    bounds;
  967.     
  968.     (void) this->CalcLocalFrameRect(bounds);
  969.  
  970.     ThrowIfNil_(mAGAObject = new AGAIconCheckBox(&bounds, AGAObject::kNoAutomaticState, mOffIconID, mOnIconID, MIconButtonObject::GetDefaultIconType(bounds.right - bounds.left)));
  971.  
  972.     if (mEnabled == triState_Off)
  973.         mAGAObject->SetEnable(AGAObject::kDisabled, AGAObject::kDontRedraw);
  974.  
  975.     mAGAObject->SetValue(this->GetValue(), AGAObject::kDontRedraw);
  976.     }
  977.  
  978. //
  979. // AGAIconCheckBoxPPX ----------------------------------------------------
  980. //
  981.  
  982. #undef Inherited
  983. #define Inherited AGAIconCheckBoxPP
  984.  
  985. AGAIconCheckBoxPPX* AGAIconCheckBoxPPX::CreateStream(LStream* inStream)
  986.     {
  987.     return new AGAIconCheckBoxPPX(inStream);
  988.     }
  989.  
  990. AGAIconCheckBoxPPX::AGAIconCheckBoxPPX(LStream* inStream)
  991. : Inherited(inStream)
  992.     {
  993.     // Read the icon IDs from the stream.
  994.  
  995.     inStream->ReadData(&mOffIconID, sizeof(mOffIconID));
  996.     inStream->ReadData(&mOnIconID, sizeof(mOnIconID));
  997.     }
  998.  
  999. AGAIconCheckBoxPPX::~AGAIconCheckBoxPPX()
  1000.     {
  1001.     }
  1002.  
  1003. //
  1004. // AGAIconRadioButtonPP ----------------------------------------------------
  1005. //
  1006.  
  1007. #undef Inherited
  1008. #define Inherited AGARadioButtonPP
  1009.  
  1010. AGAIconRadioButtonPP* AGAIconRadioButtonPP::CreateStream(LStream* inStream)
  1011.     {
  1012.     return new AGAIconRadioButtonPP(inStream);
  1013.     }
  1014.  
  1015. AGAIconRadioButtonPP::AGAIconRadioButtonPP(LStream* inStream)
  1016. : Inherited(inStream)
  1017.     {
  1018.     // Use the mUserCon for both icon IDs.
  1019.  
  1020.     mOffIconID = mUserCon;
  1021.     mOnIconID = mUserCon;
  1022.     }
  1023.  
  1024. AGAIconRadioButtonPP::~AGAIconRadioButtonPP()
  1025.     {
  1026.     }
  1027.  
  1028. void AGAIconRadioButtonPP::CreateAGAObject()
  1029.     {
  1030.     // Instantiate the particular AGAObject subclass.
  1031.     Rect    bounds;
  1032.     
  1033.     (void) this->CalcLocalFrameRect(bounds);
  1034.  
  1035.     ThrowIfNil_(mAGAObject = new AGAIconRadioButton(&bounds, kNoGroupID, kNoGroupID, AGAObject::kNoAutomaticState, mOffIconID, mOnIconID, MIconButtonObject::GetDefaultIconType(bounds.right - bounds.left)));
  1036.  
  1037.     if (mEnabled == triState_Off)
  1038.         mAGAObject->SetEnable(AGAObject::kDisabled, AGAObject::kDontRedraw);
  1039.  
  1040.     mAGAObject->SetValue(this->GetValue(), AGAObject::kDontRedraw);
  1041.     }
  1042.  
  1043. //
  1044. // AGAIconRadioButtonPPX ----------------------------------------------------
  1045. //
  1046.  
  1047. #undef Inherited
  1048. #define Inherited AGAIconRadioButtonPP
  1049.  
  1050. AGAIconRadioButtonPPX* AGAIconRadioButtonPPX::CreateStream(LStream* inStream)
  1051.     {
  1052.     return new AGAIconRadioButtonPPX(inStream);
  1053.     }
  1054.  
  1055. AGAIconRadioButtonPPX::AGAIconRadioButtonPPX(LStream* inStream)
  1056. : Inherited(inStream)
  1057.     {
  1058.     // Read the icon IDs from the stream.
  1059.  
  1060.     inStream->ReadData(&mOffIconID, sizeof(mOffIconID));
  1061.     inStream->ReadData(&mOnIconID, sizeof(mOnIconID));
  1062.     }
  1063.  
  1064. AGAIconRadioButtonPPX::~AGAIconRadioButtonPPX()
  1065.     {
  1066.     }
  1067.  
  1068. //
  1069. // AGAGroupBoxPP ----------------------------------------------------
  1070. //
  1071.  
  1072. #undef Inherited
  1073. #define Inherited LGroupBox
  1074.  
  1075. AGAGroupBoxPP* AGAGroupBoxPP::CreateStream(LStream* inStream)
  1076.     {
  1077.     return new AGAGroupBoxPP(inStream);
  1078.     }
  1079.  
  1080. AGAGroupBoxPP::AGAGroupBoxPP(LStream* inStream)
  1081. : Inherited(inStream)
  1082.     {
  1083.     // Assume primary group type, and use the mUserCon as the
  1084.     // gap pane's ID.
  1085.  
  1086.     mAGAObject = NULL;
  1087.     mIsPrimaryGroup = TRUE;
  1088.     mGapPaneID = mUserCon;
  1089.     }
  1090.  
  1091. AGAGroupBoxPP::~AGAGroupBoxPP()
  1092.     {
  1093.     // Delete AGA object if we successfully allocated it.
  1094.  
  1095.     if (mAGAObject != NULL)
  1096.         delete mAGAObject;
  1097.     }
  1098.  
  1099. void AGAGroupBoxPP::FinishCreateSelf()
  1100.     {
  1101.     // Create and set up the AGAObject.
  1102.  
  1103.     this->CreateAGAObject();
  1104.     }
  1105.  
  1106. void AGAGroupBoxPP::DrawSelf()
  1107.     {
  1108.     // Let the AGAObject draw itself.
  1109.  
  1110.     if (mAGAObject != NULL)
  1111.         mAGAObject->DrawObject();
  1112.     }
  1113.  
  1114. void AGAGroupBoxPP::EnableSelf()
  1115.     {
  1116.     // Let the AGAObject enable itself.
  1117.  
  1118.     if (mAGAObject != NULL)
  1119.         {
  1120.         this->FocusDraw();
  1121.         mAGAObject->SetEnable(AGAObject::kEnabled, AGAObject::kRedraw);
  1122.         }
  1123.     }
  1124.  
  1125. void AGAGroupBoxPP::DisableSelf()
  1126.     {
  1127.     // Let the AGAObject disable itself.
  1128.  
  1129.     if (mAGAObject != NULL)
  1130.         {
  1131.         this->FocusDraw();
  1132.         mAGAObject->SetEnable(AGAObject::kDisabled, AGAObject::kRedraw);
  1133.         }
  1134.     }
  1135.  
  1136. void AGAGroupBoxPP::CreateAGAObject()
  1137.     {
  1138.     // Instantiate the particular AGAObject subclass.
  1139.  
  1140.     Rect    bounds;
  1141.     
  1142.     (void) this->CalcLocalFrameRect(bounds);
  1143.  
  1144.     ThrowIfNil_(mAGAObject = new AGAGroupBox(&bounds, AGATextStyle(mTxtrID), mIsPrimaryGroup, mText));
  1145.  
  1146.     if (mEnabled == triState_Off)
  1147.         mAGAObject->SetEnable(AGAObject::kDisabled, AGAObject::kDontRedraw);
  1148.  
  1149.     if ((mGapPaneID != 0) && (this->GetSuperView() != NULL))
  1150.         {
  1151.         LPane*    gapPane = this->GetSuperView()->FindPaneByID(mGapPaneID);
  1152.  
  1153.         if (gapPane != NULL)
  1154.             {
  1155.             Rect    bounds;
  1156.             
  1157.             (void) gapPane->CalcLocalFrameRect(bounds);
  1158.  
  1159.             mAGAObject->SetTitleGap(5 + bounds.right - bounds.left);
  1160.             }
  1161.         }
  1162.     }
  1163.  
  1164. //
  1165. // AGAGroupBoxPPX ----------------------------------------------------
  1166. //
  1167.  
  1168. #undef Inherited
  1169. #define Inherited AGAGroupBoxPP
  1170.  
  1171. AGAGroupBoxPPX* AGAGroupBoxPPX::CreateStream(LStream* inStream)
  1172.     {
  1173.     return new AGAGroupBoxPPX(inStream);
  1174.     }
  1175.  
  1176. AGAGroupBoxPPX::AGAGroupBoxPPX(LStream* inStream)
  1177. : Inherited(inStream)
  1178.     {
  1179.     // Read the group type and gap pane ID from the stream.
  1180.  
  1181.     inStream->ReadData(&mIsPrimaryGroup, sizeof(mIsPrimaryGroup));
  1182.     inStream->ReadData(&mGapPaneID, sizeof(mGapPaneID));
  1183.     }
  1184.  
  1185. AGAGroupBoxPPX::~AGAGroupBoxPPX()
  1186.     {
  1187.     }
  1188.  
  1189. //
  1190. // AGASecondaryGroupBoxPP ----------------------------------------------------
  1191. //
  1192.  
  1193. #undef Inherited
  1194. #define Inherited AGAGroupBoxPP
  1195.  
  1196. AGASecondaryGroupBoxPP* AGASecondaryGroupBoxPP::CreateStream(LStream* inStream)
  1197.     {
  1198.     return new AGASecondaryGroupBoxPP(inStream);
  1199.     }
  1200.  
  1201. AGASecondaryGroupBoxPP::AGASecondaryGroupBoxPP(LStream* inStream)
  1202. : Inherited(inStream)
  1203.     {
  1204.     // Set to secondary group box type. Will be used when AGA object
  1205.     // is created.
  1206.  
  1207.     mIsPrimaryGroup = FALSE;
  1208.     }
  1209.  
  1210. AGASecondaryGroupBoxPP::~AGASecondaryGroupBoxPP()
  1211.     {
  1212.     }
  1213.  
  1214. //
  1215. // AGAScrollBarPP ----------------------------------------------------
  1216. //
  1217.  
  1218. #undef Inherited
  1219. #define Inherited LStdControl
  1220.  
  1221. AGAScrollBarPP* AGAScrollBarPP::CreateStream(LStream* inStream)
  1222.     {
  1223.     return new AGAScrollBarPP(inStream);
  1224.     }
  1225.  
  1226. AGAScrollBarPP::AGAScrollBarPP(LStream* inStream)
  1227. : Inherited(inStream)
  1228.     {
  1229.     mAGAObject = NULL;
  1230.     mNotificationRoutine = NULL;
  1231.     mUserData = 0;
  1232.     }
  1233.  
  1234. AGAScrollBarPP::AGAScrollBarPP(const SPaneInfo    &inPaneInfo,
  1235.                         MessageT        inValueMessage,
  1236.                         Int32            inValue,
  1237.                         Int32            inMinValue,
  1238.                         Int32            inMaxValue,
  1239.                         Int16            inControlKind,
  1240.                         ResIDT            inTextTraitsID,
  1241.                         Str255            inTitle,
  1242.                         Int32            inMacRefCon)
  1243. : Inherited(inPaneInfo, inValueMessage, inValue, inMinValue, inMaxValue, inControlKind, inTextTraitsID, inTitle, inMacRefCon)
  1244.     {
  1245.     mAGAObject = NULL;
  1246.     mNotificationRoutine = NULL;
  1247.     mUserData = 0;
  1248.     }
  1249.  
  1250. AGAScrollBarPP::~AGAScrollBarPP()
  1251.     {
  1252.     // Delete AGA object if we successfully allocated it.
  1253.  
  1254.     if (mAGAObject != NULL)
  1255.         delete mAGAObject;
  1256.     }
  1257.  
  1258. void AGAScrollBarPP::InstallNotificationRoutine(AGANotifyPPPtr notificationRoutine, void* userData)
  1259.     {
  1260.     // Save the notification routine fn pointer and user data
  1261.     // for notification handling.
  1262.  
  1263.     mNotificationRoutine = notificationRoutine;
  1264.     mUserData = userData;
  1265.     }
  1266.  
  1267. void AGAScrollBarPP::HandleNotification(SInt32 dataValue)
  1268.     {
  1269.     // Update the scrollbar value, call the installed notification
  1270.     // function, and propagate our event number.
  1271.  
  1272.     this->SetValue(dataValue);
  1273.  
  1274.     if (mNotificationRoutine != NULL)
  1275.         (*mNotificationRoutine)(this, dataValue, mUserData);
  1276.  
  1277.     this->BroadcastValueMessage();
  1278.  
  1279.     (void) this->FocusDraw();    // HandleEvent may have caused another view to draw
  1280.     }
  1281.  
  1282. void AGAScrollBarPP::FinishCreateSelf()
  1283.     {
  1284.     // Create and set up the AGAObject.
  1285.  
  1286.     this->HideSelf();    // make sure the Control Manager object is not drawn
  1287.  
  1288.     this->CreateAGAObject();
  1289.     }
  1290.  
  1291. void AGAScrollBarPP::DrawSelf()
  1292.     {
  1293.     // Let the AGAObject draw itself.
  1294.  
  1295.     if (mAGAObject != NULL)
  1296.         mAGAObject->DrawObject();
  1297.     }
  1298.  
  1299. void AGAScrollBarPP::ClickSelf(const SMouseDownEvent &inMouseDown)
  1300.     {
  1301.     // Let the AGAObject track the mouse.
  1302.  
  1303.     if (mAGAObject != NULL)
  1304.         {
  1305.         this->FocusDraw();
  1306.         
  1307.         if (mAGAObject->TrackMouse(inMouseDown.whereLocal))
  1308.             this->HotSpotResult(this->FindHotSpot(inMouseDown.whereLocal));
  1309.         }
  1310.     }
  1311.  
  1312. void AGAScrollBarPP::EnableSelf()
  1313.     {
  1314.     // Let the AGAObject enable itself.
  1315.  
  1316.     if (mAGAObject != NULL)
  1317.         {
  1318.         this->FocusDraw();
  1319.         mAGAObject->SetEnable(AGAObject::kEnabled, AGAObject::kRedraw);
  1320.         }
  1321.     }
  1322.  
  1323. void AGAScrollBarPP::DisableSelf()
  1324.     {
  1325.     // Let the AGAObject disable itself.
  1326.  
  1327.     if (mAGAObject != NULL)
  1328.         {
  1329.         this->FocusDraw();
  1330.         mAGAObject->SetEnable(AGAObject::kDisabled, AGAObject::kRedraw);
  1331.         }
  1332.     }
  1333.  
  1334. void AGAScrollBarPP::ShowSelf()
  1335.     {
  1336.     // Suppress showing the Control Manager control.
  1337.     }
  1338.  
  1339. void AGAScrollBarPP::CreateAGAObject()
  1340.     {
  1341.     // Instantiate the particular AGAObject subclass.
  1342.  
  1343.     Rect            bounds;
  1344.     
  1345.     (void) this->CalcLocalFrameRect(bounds);
  1346.  
  1347.     ThrowIfNil_(mAGAObject = new AGAScrollBar(&bounds, mMinValue, mMaxValue, mValue));
  1348.  
  1349.     mAGAObject->InstallNotificationRoutine(AGAScrollBarPP::RealAGANotifier, this);
  1350.  
  1351.     if (mEnabled == triState_Off)
  1352.         mAGAObject->SetEnable(AGAObject::kDisabled, AGAObject::kDontRedraw);
  1353.     }
  1354.  
  1355. void AGAScrollBarPP::SetValue(SInt32 inValue)
  1356.     {
  1357.     // Set the LStdControl value and the AGA object value.
  1358.  
  1359.     Inherited::SetValue(inValue);
  1360.  
  1361.     if (mAGAObject != NULL)
  1362.         {
  1363.         this->FocusDraw();
  1364.         
  1365.         mAGAObject->SetValue(inValue, AGAObject::kRedraw);
  1366.         }
  1367.     }
  1368.  
  1369. void AGAScrollBarPP::SetMinValue(SInt32 inMinValue)
  1370.     {
  1371.     // Set the LStdControl min and the AGA object min.
  1372.  
  1373.     Inherited::SetMinValue(inMinValue);
  1374.  
  1375.     if (mAGAObject != NULL)
  1376.         {
  1377.         SInt32    oldMin;
  1378.         SInt32    oldMax;
  1379.  
  1380.         this->FocusDraw();
  1381.         
  1382.         mAGAObject->GetRange(&oldMin, &oldMax);
  1383.         mAGAObject->SetRange(inMinValue, oldMax, AGAObject::kRedraw);
  1384.         }
  1385.     }
  1386.  
  1387. void AGAScrollBarPP::SetMaxValue(SInt32 inMaxValue)
  1388.     {
  1389.     // Set the LStdControl max and the AGA object max.
  1390.  
  1391.     Inherited::SetMaxValue(inMaxValue);
  1392.  
  1393.     if (mAGAObject != NULL)
  1394.         {
  1395.         SInt32    oldMin;
  1396.         SInt32    oldMax;
  1397.  
  1398.         this->FocusDraw();
  1399.         
  1400.         mAGAObject->GetRange(&oldMin, &oldMax);
  1401.         mAGAObject->SetRange(oldMin, inMaxValue, AGAObject::kRedraw);
  1402.         }
  1403.     }
  1404.  
  1405. void AGAScrollBarPP::RealAGANotifier(AGATrackingIndicator* theIndicator, SInt32 dataValue, void* userData)
  1406.     {
  1407.     // This is a static function. Cast the user data to get
  1408.     // the AGAScrollBarMA object, have it handle the notification.
  1409.  
  1410.     ((AGAScrollBarPP*) userData)->HandleNotification(dataValue);
  1411.     }
  1412.  
  1413. //
  1414. // AGAScrollerPP ----------------------------------------------------
  1415. //
  1416.  
  1417. // === Universal ProcPtrs for Callback functions ===
  1418. static ControlActionUPP    sVertSBarAction = nil;
  1419. static ControlActionUPP    sHorizSBarAction = nil;
  1420.  
  1421. #undef Inherited
  1422. #define Inherited LScroller
  1423.  
  1424. AGAScrollerPP* AGAScrollerPP::CreateStream(LStream* inStream)
  1425.     {
  1426.     return new AGAScrollerPP(inStream);
  1427.     }
  1428.  
  1429. AGAScrollerPP::AGAScrollerPP(LStream* inStream)
  1430. : Inherited(inStream)
  1431.     {
  1432.     mOldHorizontalBar = NULL;
  1433.     mOldVerticalBar = NULL;
  1434.  
  1435.     //
  1436.     // Back up in the stream so we can find out what the
  1437.     // scroll bar indents are.
  1438.     //
  1439.  
  1440.     inStream->SetMarker(-sizeof(SScrollerInfo), streamFrom_Marker);
  1441.  
  1442.     SScrollerInfo    scrollerInfo;
  1443.     inStream->ReadData(&scrollerInfo, sizeof(SScrollerInfo));
  1444.     
  1445.     //
  1446.     // Replace the standard scroll bars with AGA scroll bars.
  1447.     //
  1448.     
  1449.     this->MakeCustomScrollBars(scrollerInfo.horizBarLeftIndent,
  1450.                                scrollerInfo.horizBarRightIndent,
  1451.                                scrollerInfo.vertBarTopIndent,
  1452.                                scrollerInfo.vertBarBottomIndent);
  1453.     }
  1454.  
  1455. AGAScrollerPP::~AGAScrollerPP()
  1456.     {
  1457.     }
  1458.  
  1459. void AGAScrollerPP::FinishCreateSelf()
  1460.     {
  1461.     Inherited::FinishCreateSelf();
  1462.     
  1463.     //
  1464.     // We can now safely delete the standard scroll bar objects
  1465.     // that we have replaced with AGA scroll bars.
  1466.     //
  1467.  
  1468.     if (mOldHorizontalBar != NULL)
  1469.         {
  1470.         mOldHorizontalBar->Hide();
  1471.         delete mOldHorizontalBar;
  1472.         mOldHorizontalBar = NULL;
  1473.         }
  1474.  
  1475.     if (mOldVerticalBar != NULL)
  1476.         {
  1477.         mOldVerticalBar->Hide();
  1478.         delete mOldVerticalBar;
  1479.         mOldVerticalBar = NULL;
  1480.         }
  1481.     }
  1482.  
  1483. void AGAScrollerPP::MakeCustomScrollBars(
  1484.     Int16            inHorizBarLeftIndent,
  1485.     Int16            inHorizBarRightIndent,
  1486.     Int16            inVertBarTopIndent,
  1487.     Int16            inVertBarBottomIndent)
  1488. {
  1489. //
  1490. // NOTE: This code is lifted from LScroller::MakeScrollBars,
  1491. // modified to create our scroll bars of our AGAScrollBarPP class
  1492. // and use our form of notification that supports live scrolling.
  1493. //
  1494.  
  1495.     SPaneInfo    barInfo;                // Common information for ScrollBars
  1496.     barInfo.visible = false;            // ScrollBars aren't visible until
  1497.     barInfo.enabled = true;                //    Scroller is activated
  1498.     barInfo.userCon = 0;
  1499.     barInfo.superView = this;
  1500.     
  1501.     mOldHorizontalBar = mHorizontalBar;
  1502.     
  1503.     mHorizontalBar = nil;
  1504.     if (inHorizBarLeftIndent >= 0) {
  1505.                                         // Create Horizontal ScrollBar
  1506.         barInfo.paneID = PaneIDT_HorizontalScrollBar;    
  1507.         barInfo.width = mFrameSize.width - inHorizBarLeftIndent -
  1508.                                            inHorizBarRightIndent;
  1509.         barInfo.height = 16;
  1510.         barInfo.bindings.left = true;
  1511.         barInfo.bindings.right = true;
  1512.         barInfo.bindings.top = false;
  1513.         barInfo.bindings.bottom = true;
  1514.         barInfo.left = inHorizBarLeftIndent;
  1515.         barInfo.top = mFrameSize.height - 16;
  1516.  
  1517.         mHorizontalBar = new AGAScrollBarPP(barInfo, msg_Nothing, 0, 0, 0,
  1518.                                     scrollBarProc, 0, "\p", (Int32) this);
  1519.  
  1520.         ((AGAScrollBarPP*) mHorizontalBar)->InstallNotificationRoutine(AGAScrollerPP::ScrollBarNotifier, this);
  1521.     }
  1522.  
  1523.     mOldVerticalBar = mVerticalBar;
  1524.     
  1525.     mVerticalBar = nil;
  1526.     if (inVertBarTopIndent >= 0) {
  1527.                                         // Create Vertical ScrollBar
  1528.         barInfo.paneID = PaneIDT_VerticalScrollBar;    
  1529.         barInfo.width = 16;
  1530.         barInfo.height = mFrameSize.height - inVertBarTopIndent -
  1531.                                              inVertBarBottomIndent;
  1532.         barInfo.bindings.left = false;
  1533.         barInfo.bindings.right = true;
  1534.         barInfo.bindings.top = true;
  1535.         barInfo.bindings.bottom = true;
  1536.         barInfo.left = mFrameSize.width - 16;
  1537.         barInfo.top = inVertBarTopIndent;
  1538.  
  1539.         mVerticalBar = new AGAScrollBarPP(barInfo, msg_Nothing, 0, 0, 0,
  1540.                                     scrollBarProc, 0, "\p", (Int32) this);
  1541.  
  1542.         ((AGAScrollBarPP*) mVerticalBar)->InstallNotificationRoutine(AGAScrollerPP::ScrollBarNotifier, this);
  1543.     }
  1544. }
  1545.  
  1546. void AGAScrollerPP::HandleNotification(LPane* theScrollBar, SInt32 dataValue)
  1547.     {
  1548.     // Scroll the image to the new location specified.
  1549.     // This is similar to what LScroller does when it listens
  1550.     // to a thumb drag message.
  1551.  
  1552.     SPoint32    newScrollPosition;
  1553.     
  1554.     mScrollingView->GetScrollPosition(newScrollPosition);
  1555.  
  1556.     if (theScrollBar == mHorizontalBar)
  1557.         newScrollPosition.h = dataValue;
  1558.     else if (theScrollBar == mVerticalBar)
  1559.         newScrollPosition.v = dataValue;
  1560.  
  1561.     mScrollingView->ScrollImageTo(newScrollPosition.h, newScrollPosition.v, TRUE);
  1562.     this->AdjustScrollBars();
  1563.  
  1564.     (void) this->FocusDraw();    // scrolling view may have grabbed focus
  1565.     }
  1566.  
  1567. void AGAScrollerPP::AdjustScrollBars()
  1568.     {
  1569.     // Check the scrolling view's size compared to ours, so that
  1570.     // the scroll bars have to correct page and step sizes.
  1571.  
  1572.     AGAScrollBarPP*    horizontalBar = (AGAScrollBarPP*) mHorizontalBar;
  1573.     AGAScrollBarPP*    verticalBar = (AGAScrollBarPP*) mVerticalBar;
  1574.  
  1575.     SPoint32        scrollUnit;
  1576.     SDimension16    scrollFrameSize;
  1577.     SDimension32    scrollImageSize;
  1578.     SPoint32        scrollPosition;
  1579.     SPoint32        maxTranslation;
  1580.     SPoint32        pageStepSize;
  1581.     SPoint32        pageSize;
  1582.  
  1583.     mScrollingView->GetScrollUnit(scrollUnit);
  1584.     mScrollingView->GetFrameSize(scrollFrameSize);
  1585.     mScrollingView->GetImageSize(scrollImageSize);
  1586.     mScrollingView->GetScrollPosition(scrollPosition);
  1587.     
  1588.     // The maxTranslation is the max (pinned) scroll value.
  1589.     maxTranslation.h = scrollImageSize.width - scrollFrameSize.width;
  1590.     maxTranslation.v = scrollImageSize.height - scrollFrameSize.height;
  1591.     
  1592.     // The page step size is how far to scroll page scrolling
  1593.     pageStepSize.h = MaxSInt32(0, scrollFrameSize.width - scrollUnit.h);
  1594.     pageStepSize.v = MaxSInt32(0, scrollFrameSize.height - scrollUnit.v);
  1595.  
  1596.     // The page size is the range that is visible at once.
  1597.     // It's not the same as the page step size.
  1598.     if (scrollImageSize.width < 1)    // avoid divide by zero or weird negatives
  1599.         pageSize.h = 1;
  1600.     else
  1601.         pageSize.h = maxTranslation.h *
  1602.             (((float) scrollFrameSize.width) / ((float) scrollImageSize.width));
  1603.  
  1604.     if (scrollImageSize.height < 1)    // avoid divide by zero or weird negatives
  1605.         pageSize.v = 1;
  1606.     else
  1607.         pageSize.v = maxTranslation.v *
  1608.             (((float) scrollFrameSize.height) / ((float) scrollImageSize.height));
  1609.  
  1610.     // Update the scroll bar objects with the calculated values.
  1611.  
  1612.     if (horizontalBar != NULL)
  1613.         {
  1614.         horizontalBar->FocusDraw();
  1615.         horizontalBar->SetMaxValue(maxTranslation.h);
  1616.         horizontalBar->mAGAObject->SetPageSize(pageSize.h, AGAObject::kRedraw);
  1617.         horizontalBar->mAGAObject->SetStepSizes(scrollUnit.h, pageStepSize.h);
  1618.         horizontalBar->SetValue(scrollPosition.h);
  1619.         }
  1620.  
  1621.     if (verticalBar != NULL)
  1622.         {
  1623.         verticalBar->FocusDraw();
  1624.         verticalBar->SetMaxValue(maxTranslation.v);
  1625.         verticalBar->mAGAObject->SetPageSize(pageSize.v, AGAObject::kRedraw);
  1626.         verticalBar->mAGAObject->SetStepSizes(scrollUnit.v, pageStepSize.v);
  1627.         verticalBar->SetValue(scrollPosition.v);
  1628.         }
  1629.     }
  1630.  
  1631. void AGAScrollerPP::ScrollBarNotifier(LPane* theScrollBar, SInt32 dataValue, void* userData)
  1632.     {
  1633.     // This is a static function. Cast the user data to get
  1634.     // the AGAScrollBarMA object, have it handle the notification.
  1635.  
  1636.     ((AGAScrollerPP*) userData)->HandleNotification(theScrollBar, dataValue);
  1637.     }
  1638.  
  1639. //
  1640. // AGASliderPP ----------------------------------------------------
  1641. //
  1642.  
  1643. #undef Inherited
  1644. #define Inherited LControl
  1645.  
  1646. AGASliderPP* AGASliderPP::CreateStream(LStream* inStream)
  1647.     {
  1648.     return new AGASliderPP(inStream);
  1649.     }
  1650.  
  1651. AGASliderPP::AGASliderPP(LStream* inStream)
  1652. : Inherited(inStream)
  1653.     {
  1654.     mAGAObject = NULL;
  1655.     mLabelsResourceID = mUserCon;    // STR# resource ID of the slider labels (0 for none)
  1656.     mLabelsTextTraitsID = -1;        // -1 means standard labels style
  1657.     mSliderJustification = teFlushDefault;
  1658.     }
  1659.  
  1660. AGASliderPP::~AGASliderPP()
  1661.     {
  1662.     // Delete AGA object if we successfully allocated it.
  1663.  
  1664.     if (mAGAObject != NULL)
  1665.         delete mAGAObject;
  1666.     }
  1667.  
  1668. void AGASliderPP::FinishCreateSelf()
  1669.     {
  1670.     // Create and set up the AGAObject.
  1671.  
  1672.     this->CreateAGAObject();
  1673.     }
  1674.  
  1675. void AGASliderPP::DrawSelf()
  1676.     {
  1677.     // Let the AGAObject draw itself.
  1678.  
  1679.     if (mAGAObject != NULL)
  1680.         mAGAObject->DrawObject();
  1681.     }
  1682.  
  1683. void AGASliderPP::ClickSelf(const SMouseDownEvent &inMouseDown)
  1684.     {
  1685.     // Let the AGAObject track the mouse.
  1686.  
  1687.     if (mAGAObject != NULL)
  1688.         {
  1689.         this->FocusDraw();
  1690.         
  1691.         if (mAGAObject->TrackMouse(inMouseDown.whereLocal))
  1692.             this->HotSpotResult(this->FindHotSpot(inMouseDown.whereLocal));
  1693.         }
  1694.     }
  1695.  
  1696. void AGASliderPP::EnableSelf()
  1697.     {
  1698.     // Let the AGAObject enable itself.
  1699.  
  1700.     if (mAGAObject != NULL)
  1701.         {
  1702.         this->FocusDraw();
  1703.         mAGAObject->SetEnable(AGAObject::kEnabled, AGAObject::kRedraw);
  1704.         }
  1705.     }
  1706.  
  1707. void AGASliderPP::DisableSelf()
  1708.     {
  1709.     // Let the AGAObject disable itself.
  1710.  
  1711.     if (mAGAObject != NULL)
  1712.         {
  1713.         this->FocusDraw();
  1714.         mAGAObject->SetEnable(AGAObject::kDisabled, AGAObject::kRedraw);
  1715.         }
  1716.     }
  1717.  
  1718. void AGASliderPP::CreateAGAObject()
  1719.     {
  1720.     // Instantiate the particular AGAObject subclass.
  1721.  
  1722.     Rect    bounds;
  1723.     
  1724.     (void) this->CalcLocalFrameRect(bounds);
  1725.  
  1726.     if (mLabelsTextTraitsID == -1)
  1727.         ThrowIfNil_(mAGAObject = new AGASlider(&bounds, mMinValue, mMaxValue, mValue, gAGAStdSmallStyle, mLabelsResourceID));
  1728.     else
  1729.         ThrowIfNil_(mAGAObject = new AGASlider(&bounds, mMinValue, mMaxValue, mValue, AGATextStyle(mLabelsTextTraitsID), mLabelsResourceID));
  1730.  
  1731.     if (mSliderJustification != teFlushDefault)
  1732.         mAGAObject->SetJustification(mSliderJustification);
  1733.  
  1734.     if (mEnabled == triState_Off)
  1735.         mAGAObject->SetEnable(AGAObject::kDisabled, AGAObject::kDontRedraw);
  1736.  
  1737.     // Slider has to erase when drawing, so make sure that
  1738.     // it doesn't assume we're on a gray background.
  1739.     RGBColor    backColor;
  1740.  
  1741.     this->FocusDraw();
  1742.     this->ApplyForeAndBackColors();
  1743.     ::GetBackColor(&backColor);
  1744.     mAGAObject->SetBackgroundEraseColor(&backColor);
  1745.     }
  1746.  
  1747. void AGASliderPP::SetValue(SInt32 inValue)
  1748.     {
  1749.     // Set the slider value.
  1750.  
  1751.     if (mAGAObject != NULL)
  1752.         {
  1753.         this->FocusDraw();
  1754.         
  1755.         mAGAObject->SetValue(inValue, AGAObject::kRedraw);
  1756.         }
  1757.     }
  1758.  
  1759. void AGASliderPP::SetMinValue(SInt32 inMinValue)
  1760.     {
  1761.     // Set the slider min.
  1762.  
  1763.     if (mAGAObject != NULL)
  1764.         {
  1765.         SInt32    oldMin;
  1766.         SInt32    oldMax;
  1767.  
  1768.         this->FocusDraw();
  1769.         
  1770.         mAGAObject->GetRange(&oldMin, &oldMax);
  1771.         mAGAObject->SetRange(inMinValue, oldMax, AGAObject::kRedraw);
  1772.         }
  1773.     }
  1774.  
  1775. void AGASliderPP::SetMaxValue(SInt32 inMaxValue)
  1776.     {
  1777.     // Set the slider max.
  1778.  
  1779.     if (mAGAObject != NULL)
  1780.         {
  1781.         SInt32    oldMin;
  1782.         SInt32    oldMax;
  1783.  
  1784.         this->FocusDraw();
  1785.         
  1786.         mAGAObject->GetRange(&oldMin, &oldMax);
  1787.         mAGAObject->SetRange(oldMin, inMaxValue, AGAObject::kRedraw);
  1788.         }
  1789.     }
  1790.  
  1791. //
  1792. // AGASliderPPX ----------------------------------------------------
  1793. //
  1794.  
  1795. #undef Inherited
  1796. #define Inherited AGASliderPP
  1797.  
  1798. AGASliderPPX* AGASliderPPX::CreateStream(LStream* inStream)
  1799.     {
  1800.     return new AGASliderPPX(inStream);
  1801.     }
  1802.  
  1803. AGASliderPPX::AGASliderPPX(LStream* inStream)
  1804. : Inherited(inStream)
  1805.     {
  1806.     // Read the labels STR# ID, labels text traits ID, and
  1807.     // slider justification from the stream.
  1808.  
  1809.     inStream->ReadData(&mLabelsResourceID, sizeof(mLabelsResourceID));
  1810.     inStream->ReadData(&mLabelsTextTraitsID, sizeof(mLabelsTextTraitsID));
  1811.     inStream->ReadData(&mSliderJustification, sizeof(mSliderJustification));
  1812.     }
  1813.  
  1814. AGASliderPPX::~AGASliderPPX()
  1815.     {
  1816.     }
  1817.  
  1818. //
  1819. // AGALittleArrowsPP ----------------------------------------------------
  1820. //
  1821.  
  1822. #undef Inherited
  1823. #define Inherited LControl
  1824.  
  1825. AGALittleArrowsPP* AGALittleArrowsPP::CreateStream(LStream* inStream)
  1826.     {
  1827.     return new AGALittleArrowsPP(inStream);
  1828.     }
  1829.  
  1830. AGALittleArrowsPP::AGALittleArrowsPP(LStream* inStream)
  1831. : Inherited(inStream)
  1832.     {
  1833.     mNotificationRoutine = NULL;
  1834.     mAGAObject = NULL;
  1835.     mLinkedNumberText = NULL;
  1836.     mLinkedPaneID = mUserCon;
  1837.     }
  1838.  
  1839. AGALittleArrowsPP::~AGALittleArrowsPP()
  1840.     {
  1841.     // Delete AGA object if we successfully allocated it.
  1842.  
  1843.     if (mAGAObject != NULL)
  1844.         delete mAGAObject;
  1845.     }
  1846.  
  1847. void AGALittleArrowsPP::InstallNotificationRoutine(AGANotifyPPPtr notificationRoutine, void* userData)
  1848.     {
  1849.     // Save the notification routine fn pointer and user data
  1850.     // for notification handling.
  1851.  
  1852.     mNotificationRoutine = notificationRoutine;
  1853.     mUserData = userData;
  1854.     }
  1855.  
  1856. void AGALittleArrowsPP::HandleNotification(SInt32 deltaValue)
  1857.     {
  1858.     // Update the linked LEditField, if any, call the
  1859.     // installed notification function, and propagate our
  1860.     // hot spot result.
  1861.  
  1862.     if (mLinkedNumberText != NULL)
  1863.         {
  1864.         SInt32    oldValue = mLinkedNumberText->GetValue();
  1865.         SInt32    newValue = oldValue + deltaValue;
  1866.         
  1867.         // Constrain to our range. Only set new text value if changed.
  1868.         newValue = MinSInt32(MaxSInt32(mMinValue, newValue), mMaxValue);
  1869.         
  1870.         if (newValue != oldValue)
  1871.             {
  1872.             mLinkedNumberText->SetValue(MinSInt32(MaxSInt32(mMinValue, newValue), mMaxValue));
  1873.             mLinkedNumberText->Draw(NULL);
  1874.             }
  1875.         }
  1876.  
  1877.     if (mNotificationRoutine != NULL)
  1878.         (*mNotificationRoutine)(this, deltaValue, mUserData);
  1879.     
  1880.     this->HotSpotResult(deltaValue);
  1881.  
  1882.     this->FocusDraw();    // linked edit field prob'ly grabbed focus
  1883.     }
  1884.  
  1885. void AGALittleArrowsPP::FinishCreateSelf()
  1886.     {
  1887.     // Create and set up the AGAObject.
  1888.  
  1889.     this->CreateAGAObject();
  1890.     }
  1891.  
  1892. void AGALittleArrowsPP::DrawSelf()
  1893.     {
  1894.     // Let the AGAObject draw itself.
  1895.  
  1896.     if (mAGAObject != NULL)
  1897.         mAGAObject->DrawObject();
  1898.     }
  1899.  
  1900. void AGALittleArrowsPP::ClickSelf(const SMouseDownEvent &inMouseDown)
  1901.     {
  1902.     // Let the AGAObject track the mouse.
  1903.  
  1904.     if (mAGAObject != NULL)
  1905.         {
  1906.         this->FocusDraw();
  1907.         
  1908.         if (mAGAObject->TrackMouse(inMouseDown.whereLocal))
  1909.             this->HotSpotResult(this->FindHotSpot(inMouseDown.whereLocal));
  1910.         }
  1911.     }
  1912.  
  1913. void AGALittleArrowsPP::EnableSelf()
  1914.     {
  1915.     // Let the AGAObject enable itself.
  1916.  
  1917.     if (mAGAObject != NULL)
  1918.         {
  1919.         this->FocusDraw();
  1920.         mAGAObject->SetEnable(AGAObject::kEnabled, AGAObject::kRedraw);
  1921.         }
  1922.     }
  1923.  
  1924. void AGALittleArrowsPP::DisableSelf()
  1925.     {
  1926.     // Let the AGAObject disable itself.
  1927.  
  1928.     if (mAGAObject != NULL)
  1929.         {
  1930.         this->FocusDraw();
  1931.         mAGAObject->SetEnable(AGAObject::kDisabled, AGAObject::kRedraw);
  1932.         }
  1933.     }
  1934.  
  1935. void AGALittleArrowsPP::CreateAGAObject()
  1936.     {
  1937.     // Instantiate the particular AGAObject subclass.
  1938.  
  1939.     Rect    bounds;
  1940.     
  1941.     (void) this->CalcLocalFrameRect(bounds);
  1942.  
  1943.     ThrowIfNil_(mAGAObject = new AGALittleArrows(&bounds));
  1944.     
  1945.     mAGAObject->InstallNotificationRoutine(AGALittleArrowsPP::RealAGANotifier, this);
  1946.  
  1947.     if (mEnabled == triState_Off)
  1948.         mAGAObject->SetEnable(AGAObject::kDisabled, AGAObject::kDontRedraw);
  1949.  
  1950.     if (mLinkedPaneID != 0)
  1951.         {
  1952.         // If you bypass the RTTI here, you must ensure that the
  1953.         // pane ID specifies a pane that is a subclass of LEditField.
  1954.         
  1955.         LPane*    linkedPane = mSuperView->FindPaneByID(mLinkedPaneID);
  1956.         
  1957.         if (linkedPane != NULL)
  1958.             {
  1959. #ifndef NO_RTTI
  1960.             mLinkedNumberText = dynamic_cast<LEditField*>(linkedPane);
  1961. #else // NO_RTTI
  1962.             mLinkedNumberText = (LEditField*) linkedPane;
  1963. #endif // NO_RTTI
  1964.  
  1965.             if (mLinkedNumberText != NULL)
  1966.                 mLinkedNumberText->SetValue(mValue);
  1967.             }
  1968.         }
  1969.     }
  1970.  
  1971. void AGALittleArrowsPP::RealAGANotifier(AGALittleArrows* theAGAObject, SInt32 deltaValue, void* userData)
  1972.     {
  1973.     // This is a static function. Cast the user data to get
  1974.     // the AGAScrollerScrollBarMA object, have it handle the notification.
  1975.  
  1976.     ((AGALittleArrowsPP*) userData)->HandleNotification(deltaValue);
  1977.     }
  1978.  
  1979. //
  1980. // AGALittleArrowsPPX ----------------------------------------------------
  1981. //
  1982.  
  1983. #undef Inherited
  1984. #define Inherited AGALittleArrowsPP
  1985.  
  1986. AGALittleArrowsPPX* AGALittleArrowsPPX::CreateStream(LStream* inStream)
  1987.     {
  1988.     return new AGALittleArrowsPPX(inStream);
  1989.     }
  1990.  
  1991. AGALittleArrowsPPX::AGALittleArrowsPPX(LStream* inStream)
  1992. : Inherited(inStream)
  1993.     {
  1994.     // Read the linked LEditField pane ID from the stream.
  1995.  
  1996.     inStream->ReadData(&mLinkedPaneID, sizeof(mLinkedPaneID));
  1997.     }
  1998.  
  1999. AGALittleArrowsPPX::~AGALittleArrowsPPX()
  2000.     {
  2001.     }
  2002.  
  2003. //
  2004. // AGAPopupMenuPP ----------------------------------------------------
  2005. //
  2006.  
  2007. #undef Inherited
  2008. #define Inherited LStdPopupMenu
  2009.  
  2010. AGAPopupMenuPP* AGAPopupMenuPP::CreateStream(LStream* inStream)
  2011.     {
  2012.     return new AGAPopupMenuPP(inStream);
  2013.     }
  2014.  
  2015. AGAPopupMenuPP::AGAPopupMenuPP(LStream* inStream)
  2016. : Inherited(inStream)
  2017.     {
  2018.     mAGAObject = NULL;
  2019.     
  2020.     // OK, this is really pissing me off, so I shall vent:
  2021.     // AGAPopupMenuPP::FinishCreateSelf (not this function) needs
  2022.     // to know the popup title width. There are 3 design flaws
  2023.     // making our job harder.
  2024.     // 1.
  2025.     // The big hack also known as the popup CDEF uses the control
  2026.     // max as the title width. And once it's inited, the original
  2027.     // max value is gone. Now is too late. There is no way to obtain
  2028.     // the title width from the CDEF.
  2029.     // 2.
  2030.     // LStdPopupMenu::InitStdPopupMenu also blows away the original
  2031.     // mMaxValue of this pane object. Override, you say. Sorry,
  2032.     // InitStdPopupMenu is declared private.
  2033.     // 3.
  2034.     // Override InitStdControl, you say. Sorry, it's declared non-virtual.
  2035.     //
  2036.     // So we are stuck with backing up in the stream with hardcoded
  2037.     // byte counts, for each superclass, until we get back to the
  2038.     // LControl pane data. This is straightforward, but it feels VERY
  2039.     // nasty.
  2040.     
  2041.     SInt32    originalMarker = inStream->GetMarker();
  2042.     
  2043.     // Undo the LStdPopupMenu stream read.
  2044.     inStream->SetMarker(-sizeof(Int16), streamFrom_Marker);
  2045.     
  2046.     // Undo the LStdControl stream read.
  2047.     inStream->SetMarker(-sizeof(Int16), streamFrom_Marker);
  2048.     inStream->SetMarker(-sizeof(ResIDT), streamFrom_Marker);
  2049.     inStream->SetMarker(-sizeof(Int32), streamFrom_Marker);
  2050.     Str255    title;
  2051.     ::GetControlTitle(mMacControlH, title);
  2052.     inStream->SetMarker(-1 -title[0], streamFrom_Marker);
  2053.     
  2054.     // Undo the LControl stream read.
  2055.     inStream->SetMarker(-sizeof(SControlInfo), streamFrom_Marker);
  2056.     
  2057.     // Finally, re-read the LControl pane data.
  2058.     SControlInfo    controlInfo;
  2059.     inStream->ReadData(&controlInfo, sizeof(SControlInfo));
  2060.  
  2061.     mStashedTitleWidth = controlInfo.maxValue;    // popup CDEF uses ctl max for width
  2062.     
  2063.     // And skip forward in the stream so it's back where it
  2064.     // was before we touched it, in case a subclass is reading it.
  2065.     inStream->SetMarker(originalMarker, streamFrom_Start);
  2066.     }
  2067.  
  2068. AGAPopupMenuPP::~AGAPopupMenuPP()
  2069.     {
  2070.     // Delete AGA object if we successfully allocated it.
  2071.  
  2072.     if (mAGAObject != NULL)
  2073.         delete mAGAObject;
  2074.     }
  2075.  
  2076. void AGAPopupMenuPP::FinishCreateSelf()
  2077.     {
  2078.     // Create and set up the AGAObject.
  2079.  
  2080.     this->HideSelf();    // make sure the Control Manager object is not drawn
  2081.     
  2082.     this->CreateAGAObject();
  2083.     }
  2084.  
  2085. void AGAPopupMenuPP::DrawSelf()
  2086.     {
  2087.     // Let the AGAObject draw itself.
  2088.  
  2089.     if (mAGAObject != NULL)
  2090.         mAGAObject->DrawObject();
  2091.     }
  2092.  
  2093. void AGAPopupMenuPP::ClickSelf(const SMouseDownEvent &inMouseDown)
  2094.     {
  2095.     // Let the AGAObject track the mouse.
  2096.  
  2097.     if (mAGAObject != NULL)
  2098.         {
  2099.         this->FocusDraw();
  2100.         
  2101.         if (mAGAObject->TrackMouse(inMouseDown.whereLocal))
  2102.             {
  2103.             this->SetValue(mAGAObject->GetCurrentItemNo());
  2104.             //this->BroadcastValueMessage();
  2105.             }
  2106.         }
  2107.     }
  2108.  
  2109. void AGAPopupMenuPP::EnableSelf()
  2110.     {
  2111.     // Let the AGAObject enable itself.
  2112.  
  2113.     if (mAGAObject != NULL)
  2114.         {
  2115.         this->FocusDraw();
  2116.         mAGAObject->SetEnable(AGAObject::kEnabled, AGAObject::kRedraw);
  2117.         }
  2118.     }
  2119.  
  2120. void AGAPopupMenuPP::DisableSelf()
  2121.     {
  2122.     // Let the AGAObject disable itself.
  2123.  
  2124.     if (mAGAObject != NULL)
  2125.         {
  2126.         this->FocusDraw();
  2127.         mAGAObject->SetEnable(AGAObject::kDisabled, AGAObject::kRedraw);
  2128.         }
  2129.     }
  2130.  
  2131. void AGAPopupMenuPP::ShowSelf()
  2132.     {
  2133.     // Suppress showing the Control Manager control.
  2134.     }
  2135.  
  2136. void AGAPopupMenuPP::CreateAGAObject()
  2137.     {
  2138.     // Instantiate the particular AGAObject subclass.
  2139.  
  2140.     AGAPopupMenu::WidthAdjust    widthAdjust;
  2141.  
  2142.     Rect    bounds;
  2143.     Str255    title;
  2144.     MenuRef    theMenuRef = this->GetMacMenuH();
  2145.     SInt16    justificationValue = ::GetControlValue(mMacControlH);
  2146.     
  2147.     if (((mControlKind - popupMenuProc) & popupFixedWidth) != 0)
  2148.         widthAdjust = AGAPopupMenu::kFixedWidth;
  2149.     else
  2150.         widthAdjust = AGAPopupMenu::kSystemMDEFAdjustment;
  2151.     
  2152.     (void) this->CalcLocalFrameRect(bounds);
  2153.     ::GetControlTitle(mMacControlH, title);
  2154.  
  2155.     ThrowIfNil_(mAGAObject = new AGAPopupMenu(&bounds, mStashedTitleWidth, title, teFlushRight, AGATextStyle(mTextTraitsID), widthAdjust, this->GetMacMenuH(), AGAPopupMenu::kDontDispose));
  2156.  
  2157.     if (mEnabled == triState_Off)
  2158.         mAGAObject->SetEnable(AGAObject::kDisabled, AGAObject::kDontRedraw);
  2159.     }
  2160.  
  2161. void AGAPopupMenuPP::SetValue(SInt32 inValue)
  2162.     {
  2163.     // Set the actual LStdControl value and the AGA object value.
  2164.  
  2165.     Inherited::SetValue(inValue);
  2166.  
  2167.     if (mAGAObject != NULL)
  2168.         {
  2169.         this->FocusDraw();
  2170.         mAGAObject->SetCurrentItemNo(inValue, AGAObject::kRedraw);
  2171.         }
  2172.     }
  2173.  
  2174. //
  2175. // AGADisclosureTrianglePP ----------------------------------------------------
  2176. //
  2177.  
  2178. #undef Inherited
  2179. #define Inherited LControl
  2180.  
  2181. AGADisclosureTrianglePP* AGADisclosureTrianglePP::CreateStream(LStream* inStream)
  2182.     {
  2183.     return new AGADisclosureTrianglePP(inStream);
  2184.     }
  2185.  
  2186. AGADisclosureTrianglePP::AGADisclosureTrianglePP(LStream* inStream)
  2187. : Inherited(inStream)
  2188.     {
  2189.     mAGAObject = NULL;
  2190.     }
  2191.  
  2192. AGADisclosureTrianglePP::~AGADisclosureTrianglePP()
  2193.     {
  2194.     // Delete AGA object if we successfully allocated it.
  2195.  
  2196.     if (mAGAObject != NULL)
  2197.         delete mAGAObject;
  2198.     }
  2199.  
  2200. void AGADisclosureTrianglePP::FinishCreateSelf()
  2201.     {
  2202.     // Create and set up the AGAObject.
  2203.  
  2204.     this->CreateAGAObject();
  2205.     }
  2206.  
  2207. void AGADisclosureTrianglePP::DrawSelf()
  2208.     {
  2209.     // Let the AGAObject draw itself.
  2210.  
  2211.     if (mAGAObject != NULL)
  2212.         mAGAObject->DrawObject();
  2213.     }
  2214.  
  2215. void AGADisclosureTrianglePP::ClickSelf(const SMouseDownEvent &inMouseDown)
  2216.     {
  2217.     // Let the AGAObject track the mouse.
  2218.  
  2219.     if (mAGAObject != NULL)
  2220.         {
  2221.         this->FocusDraw();
  2222.         
  2223.         if (mAGAObject->TrackMouse(inMouseDown.whereLocal))
  2224.             this->HotSpotResult(this->FindHotSpot(inMouseDown.whereLocal));
  2225.         }
  2226.     }
  2227.  
  2228. void AGADisclosureTrianglePP::EnableSelf()
  2229.     {
  2230.     // Let the AGAObject enable itself.
  2231.  
  2232.     if (mAGAObject != NULL)
  2233.         {
  2234.         this->FocusDraw();
  2235.         mAGAObject->SetEnable(AGAObject::kEnabled, AGAObject::kRedraw);
  2236.         }
  2237.     }
  2238.  
  2239. void AGADisclosureTrianglePP::DisableSelf()
  2240.     {
  2241.     // Let the AGAObject disable itself.
  2242.  
  2243.     if (mAGAObject != NULL)
  2244.         {
  2245.         this->FocusDraw();
  2246.         mAGAObject->SetEnable(AGAObject::kDisabled, AGAObject::kRedraw);
  2247.         }
  2248.     }
  2249.  
  2250. void AGADisclosureTrianglePP::CreateAGAObject()
  2251.     {
  2252.     // Instantiate the particular AGAObject subclass.
  2253.     
  2254.     Rect    bounds;
  2255.     
  2256.     (void) this->CalcLocalFrameRect(bounds);
  2257.  
  2258.     ThrowIfNil_(mAGAObject = new AGADisclosureTriangle(&bounds, AGAObject::kAutomaticState));
  2259.     
  2260.     if (mEnabled == triState_Off)
  2261.         mAGAObject->SetEnable(AGAObject::kDisabled, AGAObject::kDontRedraw);
  2262.  
  2263.     if (mValue == 1)    // allow initial state to be set to kDisclosed
  2264.         mAGAObject->SetState(AGADisclosureTriangle::kDisclosedState, AGAObject::kDontRedraw);
  2265.  
  2266.     // Disclosure triangle has to erase when animating, so make sure that
  2267.     // it doesn't assume we're on a gray background.
  2268.     RGBColor    backColor;
  2269.  
  2270.     this->FocusDraw();
  2271.     this->ApplyForeAndBackColors();
  2272.     ::GetBackColor(&backColor);
  2273.     mAGAObject->SetBackgroundEraseColor(&backColor);
  2274.     }
  2275.  
  2276. //
  2277. // AGAProgressIndicatorPP ----------------------------------------------------
  2278. //
  2279.  
  2280. #undef Inherited
  2281. #define Inherited LControl
  2282.  
  2283. AGAProgressIndicatorPP* AGAProgressIndicatorPP::CreateStream(LStream* inStream)
  2284.     {
  2285.     return new AGAProgressIndicatorPP(inStream);
  2286.     }
  2287.  
  2288. AGAProgressIndicatorPP::AGAProgressIndicatorPP(LStream* inStream)
  2289. : Inherited(inStream)
  2290.     {
  2291.     mAGAObject = NULL;
  2292.     }
  2293.  
  2294. AGAProgressIndicatorPP::~AGAProgressIndicatorPP()
  2295.     {
  2296.     // Delete AGA object if we successfully allocated it.
  2297.  
  2298.     if (mAGAObject != NULL)
  2299.         delete mAGAObject;
  2300.     }
  2301.  
  2302. void AGAProgressIndicatorPP::FinishCreateSelf()
  2303.     {
  2304.     // Create and set up the AGAObject.
  2305.  
  2306.     this->CreateAGAObject();
  2307.     }
  2308.  
  2309. void AGAProgressIndicatorPP::DrawSelf()
  2310.     {
  2311.     // Let the AGAObject draw itself.
  2312.  
  2313.     if (mAGAObject != NULL)
  2314.         mAGAObject->DrawObject();
  2315.     }
  2316.  
  2317. void AGAProgressIndicatorPP::CreateAGAObject()
  2318.     {
  2319.     // Instantiate the particular AGAObject subclass.
  2320.     
  2321.     Rect    bounds;
  2322.     
  2323.     (void) this->CalcLocalFrameRect(bounds);
  2324.  
  2325.     ThrowIfNil_(mAGAObject = new AGAProgressIndicator(&bounds, mMinValue, mMaxValue));
  2326.     
  2327.     mAGAObject->SetValue(mValue, AGAObject::kDontRedraw);
  2328.     }
  2329.  
  2330. void AGAProgressIndicatorPP::SetValue(SInt32 inValue)
  2331.     {
  2332.     // Set the value of the LControl and the AGA object.
  2333.  
  2334.     Inherited::SetValue(inValue);
  2335.  
  2336.     if (mAGAObject != NULL)
  2337.         {
  2338.         this->FocusDraw();
  2339.         
  2340.         mAGAObject->SetValue(inValue, AGAObject::kRedraw);
  2341.         }
  2342.     }
  2343.  
  2344. void AGAProgressIndicatorPP::SetMinValue(SInt32 inMinValue)
  2345.     {
  2346.     // Set the min of the LControl and the AGA object.
  2347.  
  2348.     Inherited::SetMinValue(inMinValue);
  2349.  
  2350.     if (mAGAObject != NULL)
  2351.         {
  2352.         SInt32    oldMin;
  2353.         SInt32    oldMax;
  2354.  
  2355.         this->FocusDraw();
  2356.         
  2357.         mAGAObject->GetRange(&oldMin, &oldMax);
  2358.         mAGAObject->SetRange(inMinValue, oldMax, AGAObject::kRedraw);
  2359.         }
  2360.     }
  2361.  
  2362. void AGAProgressIndicatorPP::SetMaxValue(SInt32 inMaxValue)
  2363.     {
  2364.     // Set the max of the LControl and the AGA object.
  2365.  
  2366.     Inherited::SetMaxValue(inMaxValue);
  2367.  
  2368.     if (mAGAObject != NULL)
  2369.         {
  2370.         SInt32    oldMin;
  2371.         SInt32    oldMax;
  2372.  
  2373.         this->FocusDraw();
  2374.         
  2375.         mAGAObject->GetRange(&oldMin, &oldMax);
  2376.         mAGAObject->SetRange(oldMin, inMaxValue, AGAObject::kRedraw);
  2377.         }
  2378.     }
  2379.  
  2380. //
  2381. // AGAWhiteBackgroundAttachmentPP ----------------------------------------------------
  2382. //
  2383.  
  2384. #undef Inherited
  2385. #define Inherited LAttachment
  2386.  
  2387. AGAWhiteBackgroundAttachmentPP* AGAWhiteBackgroundAttachmentPP::CreateStream(LStream* inStream)
  2388.     {
  2389.     return new AGAWhiteBackgroundAttachmentPP(inStream);
  2390.     }
  2391.  
  2392. AGAWhiteBackgroundAttachmentPP::AGAWhiteBackgroundAttachmentPP(MessageT inMessage, Boolean inExecuteHost)
  2393. : Inherited(inMessage, inExecuteHost)
  2394.     {
  2395.     }
  2396.  
  2397. AGAWhiteBackgroundAttachmentPP::AGAWhiteBackgroundAttachmentPP(LStream *inStream)
  2398. : Inherited(inStream)
  2399.     {
  2400.     }
  2401.  
  2402. Boolean AGAWhiteBackgroundAttachmentPP::Execute(MessageT inMessage, void *ioParam)
  2403.     {
  2404.     if (inMessage == msg_DrawOrPrint)
  2405.         {
  2406.         CleansePen();
  2407.  
  2408.         // Draw the background in white, inset to avoid the border
  2409.         // frame pixels.
  2410.  
  2411.         Rect    paneFrame = *((Rect*) ioParam);
  2412.         
  2413.         ::RGBForeColor(&gAGARamp[rW]);
  2414.         ::InsetRect(&paneFrame, 1, 1);
  2415.         ::PaintRect(&paneFrame);
  2416.  
  2417.         CleansePen();
  2418.         }
  2419.     
  2420.     return TRUE;    // owner should also do its work
  2421.     }
  2422.  
  2423. //
  2424. // AGABorderFrameAttachmentPP ----------------------------------------------------
  2425. //
  2426.  
  2427. #undef Inherited
  2428. #define Inherited LAttachment
  2429.  
  2430. AGABorderFrameAttachmentPP* AGABorderFrameAttachmentPP::CreateStream(LStream* inStream)
  2431.     {
  2432.     return new AGABorderFrameAttachmentPP(inStream);
  2433.     }
  2434.  
  2435. AGABorderFrameAttachmentPP::AGABorderFrameAttachmentPP(MessageT inMessage, Boolean inExecuteHost)
  2436. : Inherited(inMessage, inExecuteHost)
  2437.     {
  2438.     }
  2439.  
  2440. AGABorderFrameAttachmentPP::AGABorderFrameAttachmentPP(LStream *inStream)
  2441. : Inherited(inStream)
  2442.     {
  2443.     }
  2444.  
  2445. Boolean AGABorderFrameAttachmentPP::Execute(MessageT inMessage, void *ioParam)
  2446.     {
  2447.     if (inMessage == msg_DrawOrPrint)
  2448.         {
  2449.         CleansePen();
  2450.  
  2451.         // Draw the frame with shading outside.
  2452.  
  2453.         enum { TL, Frame, BR, kNumColors };
  2454.  
  2455.         UInt8    colorIndex[kNumColors];
  2456.         
  2457.         // If you bypass the RTTI here, the frame will always
  2458.         // draw enabled. (Frankly, you have to look closely to see
  2459.         // the difference.)
  2460.         
  2461.         Boolean    ownerEnabled = TRUE;
  2462.         
  2463. #ifndef NO_RTTI
  2464.         LPane*    ownerPane = dynamic_cast<LPane*>(mOwnerHost);
  2465.         if (ownerPane != NULL)
  2466.             ownerEnabled = ownerPane->IsEnabled();
  2467. #endif // NO_RTTI
  2468.         
  2469.         GDIterator    iter;
  2470.         Boolean        deep;
  2471.  
  2472.         while (iter.More(deep))
  2473.             {
  2474.             Rect    paneFrame = *((Rect*) ioParam);
  2475.  
  2476.             if (deep)
  2477.                 {
  2478.                 if (ownerEnabled)
  2479.                     {
  2480.                     colorIndex[TL] = r5;
  2481.                     colorIndex[Frame] = rB;
  2482.                     colorIndex[BR] = rW;
  2483.                     }
  2484.                 else
  2485.                     {
  2486.                     colorIndex[TL] = r4;
  2487.                     colorIndex[Frame] = r10;
  2488.                     colorIndex[BR] = r1;
  2489.                     }
  2490.                 }
  2491.             else    // 1-bit
  2492.                 {
  2493.                 colorIndex[Frame] = rB;
  2494.                 
  2495.                 if (! ownerEnabled)
  2496.                     ::PenPat(&qd.gray);
  2497.                 }
  2498.             
  2499.             ::InsetRect(&paneFrame, -1, -1);
  2500.             
  2501.             if (deep)
  2502.                 {
  2503.                 ::RGBForeColor(&gAGARamp[colorIndex[TL]]);
  2504.                 ::MoveTo(paneFrame.left, paneFrame.bottom - 2);
  2505.                 ::LineTo(paneFrame.left, paneFrame.top);
  2506.                 ::LineTo(paneFrame.right - 2, paneFrame.top);
  2507.                 
  2508.                 ::RGBForeColor(&gAGARamp[colorIndex[BR]]);
  2509.                 ::MoveTo(paneFrame.left + 1, paneFrame.bottom - 1);
  2510.                 ::LineTo(paneFrame.right - 1, paneFrame.bottom - 1);
  2511.                 ::LineTo(paneFrame.right - 1, paneFrame.top + 1);
  2512.                 }
  2513.  
  2514.             ::PenPat(&qd.black);
  2515.             }
  2516.  
  2517.         CleansePen();
  2518.         }
  2519.  
  2520.     return TRUE;    // owner should also do its work
  2521.     }
  2522.  
  2523. //
  2524. // AGAEditFieldPP ----------------------------------------------------
  2525. //
  2526.  
  2527. #undef Inherited
  2528. #define Inherited LEditField
  2529.  
  2530. AGAEditFieldPP* AGAEditFieldPP::CreateStream(LStream* inStream)
  2531.     {
  2532.     return new AGAEditFieldPP(inStream);
  2533.     }
  2534.  
  2535. AGAEditFieldPP::AGAEditFieldPP(LStream* inStream)
  2536. : Inherited(inStream)
  2537.     {
  2538.     // Add the attachments that make this edit field AGA-compliant.
  2539.  
  2540.     this->AddAttachment(new AGAWhiteBackgroundAttachmentPP);
  2541.     this->AddAttachment(new AGABorderFrameAttachmentPP);
  2542.     }
  2543.  
  2544. AGAEditFieldPP::~AGAEditFieldPP()
  2545.     {
  2546.     }
  2547.  
  2548. void AGAEditFieldPP::DrawBox()
  2549.     {
  2550. // NOTE: THIS FIRST SECTION IS LIFTED VERBATIM FROM LEditField::DrawBox
  2551.  
  2552.         // Box around an EditField is outset from the Text by 2 pixels.
  2553.         // The box itself is 1 pixel thick, drawn in the foreground color
  2554.         // of the Pane (not necessarily the same as the text color). If
  2555.         // the EditField is disabled, the box draws with a gray pattern.
  2556.         //
  2557.         // The 1 pixel rectangle between the box and the text draws in
  2558.         // the background color of the text.
  2559.  
  2560.     StColorState    saveColors;            // Preserve color state
  2561.     Rect            frame;
  2562.     CalcLocalFrameRect(frame);
  2563.     ::PenNormal();
  2564.     
  2565.         // Draw empty area between Box and Text. On entry, the fore
  2566.         // and back colors for the Text are in effect (as set in FocusDraw).
  2567.         // Use Text back color as the fore color for the empty area.
  2568.     
  2569.     ::InsetRect(&frame, 1, 1);
  2570.     RGBColor    emptyColor;
  2571.     ::GetBackColor(&emptyColor);
  2572.     ::RGBForeColor(&emptyColor);
  2573.     ::FrameRect(&frame);
  2574.  
  2575.         // Draw border around EditField
  2576.         
  2577.     ::InsetRect(&frame, -1, -1);
  2578.     
  2579. // REMAINING CODE PERFORMS PROPER GRAYSCALE DIMMING:
  2580.     
  2581.     GDIterator    iter;
  2582.     Boolean        deep;
  2583.     
  2584.     while (iter.More(deep))
  2585.         {
  2586.         if (deep)
  2587.             {
  2588.             ::PenPat(&qd.black);
  2589.  
  2590.             if (mEnabled == triState_Off)
  2591.                 ::RGBForeColor(&gAGARamp[r10]);
  2592.             else
  2593.                 ::RGBForeColor(&gAGARamp[rB]);
  2594.             }
  2595.         else
  2596.             {
  2597.             ::RGBForeColor(&gAGARamp[rB]);
  2598.  
  2599.             if (mEnabled == triState_Off)
  2600.                 ::PenPat(&qd.gray);
  2601.             else
  2602.                 ::PenPat(&qd.black);
  2603.             }
  2604.  
  2605.         ::FrameRect(&frame);
  2606.         }
  2607.     }
  2608.  
  2609. //
  2610. // AGATextEditPP ----------------------------------------------------
  2611. //
  2612.  
  2613. #undef Inherited
  2614. #define Inherited LTextEdit
  2615.  
  2616. AGATextEditPP* AGATextEditPP::CreateStream(LStream* inStream)
  2617.     {
  2618.     return new AGATextEditPP(inStream);
  2619.     }
  2620.  
  2621. AGATextEditPP::AGATextEditPP(LStream* inStream)
  2622. : Inherited(inStream)
  2623.     {
  2624.     // Add the attachments that make this edit field AGA-compliant.
  2625.  
  2626.     this->AddAttachment(new AGAWhiteBackgroundAttachmentPP);
  2627.     this->AddAttachment(new AGABorderFrameAttachmentPP);
  2628.     }
  2629.  
  2630. AGATextEditPP::~AGATextEditPP()
  2631.     {
  2632.     }
  2633.  
  2634. //
  2635. // AGASeparatorPP ----------------------------------------------------
  2636. //
  2637.  
  2638. #undef Inherited
  2639. #define Inherited LPane
  2640.  
  2641. AGASeparatorPP* AGASeparatorPP::CreateStream(LStream* inStream)
  2642.     {
  2643.     return new AGASeparatorPP(inStream);
  2644.     }
  2645.  
  2646. AGASeparatorPP::AGASeparatorPP(LStream* inStream)
  2647. : Inherited(inStream)
  2648.     {
  2649.     mAGAObject = NULL;
  2650.     }
  2651.  
  2652. AGASeparatorPP::~AGASeparatorPP()
  2653.     {
  2654.     // Delete AGA object if we successfully allocated it.
  2655.  
  2656.     if (mAGAObject != NULL)
  2657.         delete mAGAObject;
  2658.     }
  2659.  
  2660. void AGASeparatorPP::FinishCreateSelf()
  2661.     {
  2662.     // Create and set up the AGAObject.
  2663.  
  2664.     this->CreateAGAObject();
  2665.     }
  2666.  
  2667. void AGASeparatorPP::DrawSelf()
  2668.     {
  2669.     // Let the AGAObject draw itself.
  2670.  
  2671.     if (mAGAObject != NULL)
  2672.         mAGAObject->DrawObject();
  2673.     }
  2674.  
  2675. void AGASeparatorPP::CreateAGAObject()
  2676.     {
  2677.     // Instantiate the particular AGAObject subclass.
  2678.     
  2679.     Rect    bounds;
  2680.     
  2681.     (void) this->CalcLocalFrameRect(bounds);
  2682.  
  2683.     ThrowIfNil_(mAGAObject = new AGASeparator(&bounds));
  2684.     }
  2685.  
  2686. //
  2687. // AGACaptionPP ----------------------------------------------------
  2688. //
  2689.  
  2690. #undef Inherited
  2691. #define Inherited LCaption
  2692.  
  2693. AGACaptionPP* AGACaptionPP::CreateStream(LStream* inStream)
  2694.     {
  2695.     return new AGACaptionPP(inStream);
  2696.     }
  2697.  
  2698. AGACaptionPP::AGACaptionPP(LStream* inStream)
  2699. : Inherited(inStream)
  2700.     {
  2701.     mAGAObject = NULL;
  2702.     }
  2703.  
  2704. AGACaptionPP::~AGACaptionPP()
  2705.     {
  2706.     // Delete AGA object if we successfully allocated it.
  2707.  
  2708.     if (mAGAObject != NULL)
  2709.         delete mAGAObject;
  2710.     }
  2711.  
  2712. void AGACaptionPP::FinishCreateSelf()
  2713.     {
  2714.     // Create and set up the AGAObject.
  2715.  
  2716.     this->CreateAGAObject();
  2717.     }
  2718.  
  2719. void AGACaptionPP::DrawSelf()
  2720.     {
  2721.     // Let the AGAObject draw itself.
  2722.  
  2723.     if (mAGAObject != NULL)
  2724.         mAGAObject->DrawObject();
  2725.     }
  2726.  
  2727. void AGACaptionPP::SetDescriptor(ConstStringPtr inDescriptor)
  2728.     {
  2729.     Inherited::SetDescriptor(inDescriptor);
  2730.     
  2731.     // Install the new text in the AGA object. Don't tell it
  2732.     // to redraw; the redraw comes from the caller.
  2733.  
  2734.     Str255    newText;
  2735.     this->GetDescriptor(newText);
  2736.     mAGAObject->SetTitle(newText, AGAObject::kDontRedraw);
  2737.     }
  2738.  
  2739. void AGACaptionPP::SetValue(SInt32 inValue)
  2740.     {
  2741.     Inherited::SetValue(inValue);
  2742.     
  2743.     // Install the new text in the AGA object. Don't tell it
  2744.     // to redraw; the redraw comes from the caller.
  2745.  
  2746.     Str255    newText;
  2747.     this->GetDescriptor(newText);
  2748.     mAGAObject->SetTitle(newText, AGAObject::kDontRedraw);
  2749.     }
  2750.  
  2751. void AGACaptionPP::CreateAGAObject()
  2752.     {
  2753.     // Instantiate the particular AGAObject subclass.
  2754.     
  2755.     Rect    bounds;
  2756.     
  2757.     (void) this->CalcLocalFrameRect(bounds);
  2758.  
  2759.     ThrowIfNil_(mAGAObject = new AGAStaticText(&bounds, AGATextStyle(mTxtrID), GetTextTraitsJustification(mTxtrID)));
  2760.     
  2761.     this->SetDescriptor(mText);    // make sure AGA object text is inited
  2762.     }
  2763.  
  2764. //
  2765. // AGAFocusBoxPP ----------------------------------------------------
  2766. //
  2767.  
  2768. #undef Inherited
  2769. #define Inherited LFocusBox
  2770.  
  2771. AGAFocusBoxPP* AGAFocusBoxPP::CreateStream(LStream* inStream)
  2772.     {
  2773.     return new AGAFocusBoxPP(inStream);
  2774.     }
  2775.  
  2776. AGAFocusBoxPP::AGAFocusBoxPP()
  2777. : Inherited()
  2778.     {
  2779.     }
  2780.  
  2781. AGAFocusBoxPP::AGAFocusBoxPP(const LFocusBox &inOriginal)
  2782. : Inherited(inOriginal)
  2783.     {
  2784.     }
  2785.  
  2786. AGAFocusBoxPP::AGAFocusBoxPP(LStream* inStream)
  2787. : Inherited(inStream)
  2788.     {
  2789.     }
  2790.  
  2791. AGAFocusBoxPP::~AGAFocusBoxPP()
  2792.     {
  2793.     }
  2794.  
  2795. void AGAFocusBoxPP::DrawSelf()
  2796.     {
  2797.     // Draw the AGA-style focus frame.
  2798.  
  2799.     GDIterator    iter;
  2800.     Boolean        deep;
  2801.  
  2802.     RgnHandle borderRegion = ::NewRgn();
  2803.         
  2804.     while (iter.More(deep))
  2805.         {
  2806.         if (deep)
  2807.             ::RGBForeColor(&gAGARamp[r8]);
  2808.         else
  2809.             ::RGBForeColor(&gAGARamp[rB]);
  2810.  
  2811.         this->ComputeBorderRegion(borderRegion);
  2812.         PaintRgn(borderRegion);
  2813.         }
  2814.     
  2815.     ::DisposeRgn(borderRegion);
  2816.     }
  2817.  
  2818. void AGAFocusBoxPP::ComputeBorderRegion(RgnHandle borderRegion)
  2819.     {
  2820.     // Compute the border region to be painted.
  2821.  
  2822.     RgnHandle    innerRegion = ::NewRgn();
  2823.     Rect        bounds;
  2824.     
  2825.     (void) this->CalcLocalFrameRect(bounds);
  2826.  
  2827.     ::OpenRgn();
  2828.     ::FrameRoundRect(&bounds, 4, 4);
  2829.     ::CloseRgn(borderRegion);
  2830.  
  2831.     ::InsetRect(&bounds, 2, 2);
  2832.     ::RectRgn(innerRegion, &bounds);
  2833.     ::DiffRgn(borderRegion, innerRegion, borderRegion);
  2834.     
  2835.     ::DisposeRgn(innerRegion);
  2836.     }
  2837.  
  2838. //
  2839. // AGAListBoxPP ----------------------------------------------------
  2840. //
  2841.  
  2842. #undef Inherited
  2843. #define Inherited LListBox
  2844.  
  2845. AGAListBoxPP* AGAListBoxPP::CreateStream(LStream* inStream)
  2846.     {
  2847.     return new AGAListBoxPP(inStream);
  2848.     }
  2849.  
  2850. AGAListBoxPP::AGAListBoxPP(LStream* inStream)
  2851. : Inherited(inStream)
  2852.     {
  2853.     }
  2854.  
  2855. AGAListBoxPP::~AGAListBoxPP()
  2856.     {
  2857.     }
  2858.  
  2859. void AGAListBoxPP::FinishCreateSelf()
  2860.     {
  2861.     // Replace the standard LFocusBox with an AGAFocusBoxPP
  2862.     // initialized from the existing one.
  2863.     
  2864.     if (mFocusBox != NULL)
  2865.         {
  2866.         AGAFocusBoxPP*    newFocusBox = new AGAFocusBoxPP(*mFocusBox);
  2867.         
  2868.         delete mFocusBox;
  2869.         
  2870.         mFocusBox = newFocusBox;
  2871.         mFocusBox->AttachPane(this, FALSE);
  2872.         
  2873.         // The standard LFocusBox is smaller by 1 pixel on each
  2874.         // side than the AGA focus box, so expand ours from where
  2875.         // LFocusBox::AttachPane located and sized it.
  2876.         
  2877.         mFocusBox->MoveBy(-1, -1, TRUE);
  2878.         mFocusBox->ResizeFrameBy(2, 2, TRUE);
  2879.         }
  2880.  
  2881.     // Attach the white background and border frame attachments.
  2882.     
  2883.     this->AddAttachment(new AGAWhiteBackgroundAttachmentPP);
  2884.     this->AddAttachment(new AGABorderFrameAttachmentPP);
  2885.     }
  2886.  
  2887.